]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_bmp.c
Merge pull request #11643 from ARShreenidhi/df_or_ntw_auto
[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;
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 return true;
1124 }
1125
1126 static struct bmp_queue_entry *bmp_pull(struct bmp *bmp)
1127 {
1128 struct bmp_queue_entry *bqe;
1129
1130 bqe = bmp->queuepos;
1131 if (!bqe)
1132 return NULL;
1133
1134 bmp->queuepos = bmp_qlist_next(&bmp->targets->updlist, bqe);
1135
1136 bqe->refcount--;
1137 if (!bqe->refcount) {
1138 bmp_qhash_del(&bmp->targets->updhash, bqe);
1139 bmp_qlist_del(&bmp->targets->updlist, bqe);
1140 }
1141 return bqe;
1142 }
1143
1144 static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr)
1145 {
1146 struct bmp_queue_entry *bqe;
1147 struct peer *peer;
1148 struct bgp_dest *bn;
1149 bool written = false;
1150
1151 bqe = bmp_pull(bmp);
1152 if (!bqe)
1153 return false;
1154
1155 afi_t afi = bqe->afi;
1156 safi_t safi = bqe->safi;
1157
1158 switch (bmp->afistate[afi][safi]) {
1159 case BMP_AFI_INACTIVE:
1160 case BMP_AFI_NEEDSYNC:
1161 goto out;
1162 case BMP_AFI_SYNC:
1163 if (prefix_cmp(&bqe->p, &bmp->syncpos) <= 0)
1164 /* currently syncing but have already passed this
1165 * prefix => send it. */
1166 break;
1167
1168 /* currently syncing & haven't reached this prefix yet
1169 * => it'll be sent as part of the table sync, no need here */
1170 goto out;
1171 case BMP_AFI_LIVE:
1172 break;
1173 }
1174
1175 peer = QOBJ_GET_TYPESAFE(bqe->peerid, peer);
1176 if (!peer) {
1177 zlog_info("bmp: skipping queued item for deleted peer");
1178 goto out;
1179 }
1180 if (!peer_established(peer))
1181 goto out;
1182
1183 bn = bgp_node_lookup(bmp->targets->bgp->rib[afi][safi], &bqe->p);
1184 struct prefix_rd *prd = NULL;
1185 if ((bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) ||
1186 (bqe->safi == SAFI_MPLS_VPN))
1187 prd = &bqe->rd;
1188
1189 if (bmp->targets->afimon[afi][safi] & BMP_MON_POSTPOLICY) {
1190 struct bgp_path_info *bpi;
1191
1192 for (bpi = bn ? bgp_dest_get_bgp_path_info(bn) : NULL; bpi;
1193 bpi = bpi->next) {
1194 if (!CHECK_FLAG(bpi->flags, BGP_PATH_VALID))
1195 continue;
1196 if (bpi->peer == peer)
1197 break;
1198 }
1199
1200 bmp_monitor(bmp, peer, BMP_PEER_FLAG_L, &bqe->p, prd,
1201 bpi ? bpi->attr : NULL, afi, safi,
1202 bpi ? bpi->uptime : monotime(NULL));
1203 written = true;
1204 }
1205
1206 if (bmp->targets->afimon[afi][safi] & BMP_MON_PREPOLICY) {
1207 struct bgp_adj_in *adjin;
1208
1209 for (adjin = bn ? bn->adj_in : NULL; adjin;
1210 adjin = adjin->next) {
1211 if (adjin->peer == peer)
1212 break;
1213 }
1214 bmp_monitor(bmp, peer, 0, &bqe->p, prd,
1215 adjin ? adjin->attr : NULL, afi, safi,
1216 adjin ? adjin->uptime : monotime(NULL));
1217 written = true;
1218 }
1219
1220 out:
1221 if (!bqe->refcount)
1222 XFREE(MTYPE_BMP_QUEUE, bqe);
1223 return written;
1224 }
1225
1226 static void bmp_wrfill(struct bmp *bmp, struct pullwr *pullwr)
1227 {
1228 switch(bmp->state) {
1229 case BMP_PeerUp:
1230 bmp_send_peerup(bmp);
1231 bmp->state = BMP_Run;
1232 break;
1233
1234 case BMP_Run:
1235 if (bmp_wrmirror(bmp, pullwr))
1236 break;
1237 if (bmp_wrqueue(bmp, pullwr))
1238 break;
1239 if (bmp_wrsync(bmp, pullwr))
1240 break;
1241 break;
1242 }
1243 }
1244
1245 static void bmp_wrerr(struct bmp *bmp, struct pullwr *pullwr, bool eof)
1246 {
1247 if (eof)
1248 zlog_info("bmp[%s] disconnected", bmp->remote);
1249 else
1250 flog_warn(EC_LIB_SYSTEM_CALL, "bmp[%s] connection error: %s",
1251 bmp->remote, strerror(errno));
1252
1253 bmp_close(bmp);
1254 bmp_free(bmp);
1255 }
1256
1257 static void bmp_process_one(struct bmp_targets *bt, struct bgp *bgp, afi_t afi,
1258 safi_t safi, struct bgp_dest *bn, struct peer *peer)
1259 {
1260 struct bmp *bmp;
1261 struct bmp_queue_entry *bqe, bqeref;
1262 size_t refcount;
1263
1264 refcount = bmp_session_count(&bt->sessions);
1265 if (refcount == 0)
1266 return;
1267
1268 memset(&bqeref, 0, sizeof(bqeref));
1269 prefix_copy(&bqeref.p, bgp_dest_get_prefix(bn));
1270 bqeref.peerid = peer->qobj_node.nid;
1271 bqeref.afi = afi;
1272 bqeref.safi = safi;
1273
1274 if ((afi == AFI_L2VPN && safi == SAFI_EVPN && bn->pdest) ||
1275 (safi == SAFI_MPLS_VPN))
1276 prefix_copy(&bqeref.rd,
1277 (struct prefix_rd *)bgp_dest_get_prefix(bn->pdest));
1278
1279 bqe = bmp_qhash_find(&bt->updhash, &bqeref);
1280 if (bqe) {
1281 if (bqe->refcount >= refcount)
1282 /* nothing to do here */
1283 return;
1284
1285 bmp_qlist_del(&bt->updlist, bqe);
1286 } else {
1287 bqe = XMALLOC(MTYPE_BMP_QUEUE, sizeof(*bqe));
1288 memcpy(bqe, &bqeref, sizeof(*bqe));
1289
1290 bmp_qhash_add(&bt->updhash, bqe);
1291 }
1292
1293 bqe->refcount = refcount;
1294 bmp_qlist_add_tail(&bt->updlist, bqe);
1295
1296 frr_each (bmp_session, &bt->sessions, bmp)
1297 if (!bmp->queuepos)
1298 bmp->queuepos = bqe;
1299 }
1300
1301 static int bmp_process(struct bgp *bgp, afi_t afi, safi_t safi,
1302 struct bgp_dest *bn, struct peer *peer, bool withdraw)
1303 {
1304 struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
1305 struct bmp_targets *bt;
1306 struct bmp *bmp;
1307
1308 if (frrtrace_enabled(frr_bgp, bmp_process)) {
1309 char pfxprint[PREFIX2STR_BUFFER];
1310
1311 prefix2str(&bn->p, pfxprint, sizeof(pfxprint));
1312 frrtrace(5, frr_bgp, bmp_process, peer, pfxprint, afi, safi,
1313 withdraw);
1314 }
1315
1316 if (!bmpbgp)
1317 return 0;
1318
1319 frr_each(bmp_targets, &bmpbgp->targets, bt) {
1320 if (!bt->afimon[afi][safi])
1321 continue;
1322
1323 bmp_process_one(bt, bgp, afi, safi, bn, peer);
1324
1325 frr_each(bmp_session, &bt->sessions, bmp) {
1326 pullwr_bump(bmp->pullwr);
1327 }
1328 }
1329 return 0;
1330 }
1331
1332 static void bmp_stat_put_u32(struct stream *s, size_t *cnt, uint16_t type,
1333 uint32_t value)
1334 {
1335 stream_putw(s, type);
1336 stream_putw(s, 4);
1337 stream_putl(s, value);
1338 (*cnt)++;
1339 }
1340
1341 static void bmp_stats(struct thread *thread)
1342 {
1343 struct bmp_targets *bt = THREAD_ARG(thread);
1344 struct stream *s;
1345 struct peer *peer;
1346 struct listnode *node;
1347 struct timeval tv;
1348
1349 if (bt->stat_msec)
1350 thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
1351 &bt->t_stats);
1352
1353 gettimeofday(&tv, NULL);
1354
1355 /* Walk down all peers */
1356 for (ALL_LIST_ELEMENTS_RO(bt->bgp->peer, node, peer)) {
1357 size_t count = 0, count_pos, len;
1358
1359 if (!peer_established(peer))
1360 continue;
1361
1362 s = stream_new(BGP_MAX_PACKET_SIZE);
1363 bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_STATISTICS_REPORT);
1364 bmp_per_peer_hdr(s, peer, 0, &tv);
1365
1366 count_pos = stream_get_endp(s);
1367 stream_putl(s, 0);
1368
1369 bmp_stat_put_u32(s, &count, BMP_STATS_PFX_REJECTED,
1370 peer->stat_pfx_filter);
1371 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_LOOP_ASPATH,
1372 peer->stat_pfx_aspath_loop);
1373 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_LOOP_ORIGINATOR,
1374 peer->stat_pfx_originator_loop);
1375 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_LOOP_CLUSTER,
1376 peer->stat_pfx_cluster_loop);
1377 bmp_stat_put_u32(s, &count, BMP_STATS_PFX_DUP_WITHDRAW,
1378 peer->stat_pfx_dup_withdraw);
1379 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_7606_WITHDRAW,
1380 peer->stat_upd_7606);
1381 bmp_stat_put_u32(s, &count, BMP_STATS_FRR_NH_INVALID,
1382 peer->stat_pfx_nh_invalid);
1383
1384 stream_putl_at(s, count_pos, count);
1385
1386 len = stream_get_endp(s);
1387 stream_putl_at(s, BMP_LENGTH_POS, len);
1388
1389 bmp_send_all(bt->bmpbgp, s);
1390 }
1391 }
1392
1393 /* read from the BMP socket to detect session termination */
1394 static void bmp_read(struct thread *t)
1395 {
1396 struct bmp *bmp = THREAD_ARG(t);
1397 char buf[1024];
1398 ssize_t n;
1399
1400 bmp->t_read = NULL;
1401
1402 n = read(bmp->socket, buf, sizeof(buf));
1403 if (n >= 1) {
1404 zlog_info("bmp[%s]: unexpectedly received %zu bytes", bmp->remote, n);
1405 } else if (n == 0) {
1406 /* the TCP session was terminated by the far end */
1407 bmp_wrerr(bmp, NULL, true);
1408 return;
1409 } else if (!(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
1410 /* the TCP session experienced a fatal error, likely a timeout */
1411 bmp_wrerr(bmp, NULL, false);
1412 return;
1413 }
1414
1415 thread_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read);
1416 }
1417
1418 static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock)
1419 {
1420 union sockunion su, *sumem;
1421 struct prefix p;
1422 int on = 1;
1423 struct access_list *acl = NULL;
1424 enum filter_type ret;
1425 char buf[SU_ADDRSTRLEN];
1426 struct bmp *bmp;
1427
1428 sumem = sockunion_getpeername(bmp_sock);
1429 if (!sumem) {
1430 close(bmp_sock);
1431 return NULL;
1432 }
1433 memcpy(&su, sumem, sizeof(su));
1434 sockunion_free(sumem);
1435
1436 set_nonblocking(bmp_sock);
1437 set_cloexec(bmp_sock);
1438
1439 if (!sockunion2hostprefix(&su, &p)) {
1440 close(bmp_sock);
1441 return NULL;
1442 }
1443
1444 acl = NULL;
1445 switch (p.family) {
1446 case AF_INET:
1447 acl = access_list_lookup(AFI_IP, bt->acl_name);
1448 break;
1449 case AF_INET6:
1450 acl = access_list_lookup(AFI_IP6, bt->acl6_name);
1451 break;
1452 default:
1453 break;
1454 }
1455
1456 ret = FILTER_PERMIT;
1457 if (acl) {
1458 ret = access_list_apply(acl, &p);
1459 }
1460
1461 sockunion2str(&su, buf, SU_ADDRSTRLEN);
1462 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%u",
1463 su.sa.sa_family == AF_INET
1464 ? ntohs(su.sin.sin_port)
1465 : ntohs(su.sin6.sin6_port));
1466
1467 if (ret == FILTER_DENY) {
1468 bt->cnt_aclrefused++;
1469 zlog_info("bmp[%s] connection refused by access-list", buf);
1470 close(bmp_sock);
1471 return NULL;
1472 }
1473 bt->cnt_accept++;
1474
1475 if (setsockopt(bmp_sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
1476 flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt SO_KEEPALIVE: %s(%d)",
1477 bmp_sock, safe_strerror(errno), errno);
1478 if (setsockopt(bmp_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
1479 flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt TCP_NODELAY: %s(%d)",
1480 bmp_sock, safe_strerror(errno), errno);
1481
1482 zlog_info("bmp[%s] connection established", buf);
1483
1484 /* Allocate new BMP structure and set up default values. */
1485 bmp = bmp_new(bt, bmp_sock);
1486 strlcpy(bmp->remote, buf, sizeof(bmp->remote));
1487
1488 bmp->state = BMP_PeerUp;
1489 bmp->pullwr = pullwr_new(bm->master, bmp_sock, bmp, bmp_wrfill,
1490 bmp_wrerr);
1491 thread_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read);
1492 bmp_send_initiation(bmp);
1493
1494 return bmp;
1495 }
1496
1497 /* Accept BMP connection. */
1498 static void bmp_accept(struct thread *thread)
1499 {
1500 union sockunion su;
1501 struct bmp_listener *bl = THREAD_ARG(thread);
1502 int bmp_sock;
1503
1504 /* We continue hearing BMP socket. */
1505 thread_add_read(bm->master, bmp_accept, bl, bl->sock, &bl->t_accept);
1506
1507 memset(&su, 0, sizeof(union sockunion));
1508
1509 /* We can handle IPv4 or IPv6 socket. */
1510 bmp_sock = sockunion_accept(bl->sock, &su);
1511 if (bmp_sock < 0) {
1512 zlog_info("bmp: accept_sock failed: %s", safe_strerror(errno));
1513 return;
1514 }
1515 bmp_open(bl->targets, bmp_sock);
1516 }
1517
1518 static void bmp_close(struct bmp *bmp)
1519 {
1520 struct bmp_queue_entry *bqe;
1521 struct bmp_mirrorq *bmq;
1522
1523 THREAD_OFF(bmp->t_read);
1524
1525 if (bmp->active)
1526 bmp_active_disconnected(bmp->active);
1527
1528 while ((bmq = bmp_pull_mirror(bmp)))
1529 if (!bmq->refcount)
1530 XFREE(MTYPE_BMP_MIRRORQ, bmq);
1531 while ((bqe = bmp_pull(bmp)))
1532 if (!bqe->refcount)
1533 XFREE(MTYPE_BMP_QUEUE, bqe);
1534
1535 THREAD_OFF(bmp->t_read);
1536 pullwr_del(bmp->pullwr);
1537 close(bmp->socket);
1538 }
1539
1540 static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp)
1541 {
1542 struct bmp_bgp dummy = { .bgp = bgp };
1543 return bmp_bgph_find(&bmp_bgph, &dummy);
1544 }
1545
1546 static struct bmp_bgp *bmp_bgp_get(struct bgp *bgp)
1547 {
1548 struct bmp_bgp *bmpbgp;
1549
1550 bmpbgp = bmp_bgp_find(bgp);
1551 if (bmpbgp)
1552 return bmpbgp;
1553
1554 bmpbgp = XCALLOC(MTYPE_BMP, sizeof(*bmpbgp));
1555 bmpbgp->bgp = bgp;
1556 bmpbgp->mirror_qsizelimit = ~0UL;
1557 bmp_mirrorq_init(&bmpbgp->mirrorq);
1558 bmp_bgph_add(&bmp_bgph, bmpbgp);
1559
1560 return bmpbgp;
1561 }
1562
1563 static void bmp_bgp_put(struct bmp_bgp *bmpbgp)
1564 {
1565 struct bmp_targets *bt;
1566 struct bmp_listener *bl;
1567
1568 bmp_bgph_del(&bmp_bgph, bmpbgp);
1569
1570 frr_each_safe (bmp_targets, &bmpbgp->targets, bt) {
1571 frr_each_safe (bmp_listeners, &bt->listeners, bl)
1572 bmp_listener_put(bl);
1573
1574 bmp_targets_put(bt);
1575 }
1576
1577 bmp_mirrorq_fini(&bmpbgp->mirrorq);
1578 XFREE(MTYPE_BMP, bmpbgp);
1579 }
1580
1581 static int bmp_bgp_del(struct bgp *bgp)
1582 {
1583 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
1584
1585 if (bmpbgp)
1586 bmp_bgp_put(bmpbgp);
1587 return 0;
1588 }
1589
1590 static struct bmp_bgp_peer *bmp_bgp_peer_find(uint64_t peerid)
1591 {
1592 struct bmp_bgp_peer dummy = { .peerid = peerid };
1593 return bmp_peerh_find(&bmp_peerh, &dummy);
1594 }
1595
1596 static struct bmp_bgp_peer *bmp_bgp_peer_get(struct peer *peer)
1597 {
1598 struct bmp_bgp_peer *bbpeer;
1599
1600 bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
1601 if (bbpeer)
1602 return bbpeer;
1603
1604 bbpeer = XCALLOC(MTYPE_BMP_PEER, sizeof(*bbpeer));
1605 bbpeer->peerid = peer->qobj_node.nid;
1606 bmp_peerh_add(&bmp_peerh, bbpeer);
1607
1608 return bbpeer;
1609 }
1610
1611 static struct bmp_targets *bmp_targets_find1(struct bgp *bgp, const char *name)
1612 {
1613 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
1614 struct bmp_targets dummy;
1615
1616 if (!bmpbgp)
1617 return NULL;
1618 dummy.name = (char *)name;
1619 return bmp_targets_find(&bmpbgp->targets, &dummy);
1620 }
1621
1622 static struct bmp_targets *bmp_targets_get(struct bgp *bgp, const char *name)
1623 {
1624 struct bmp_targets *bt;
1625
1626 bt = bmp_targets_find1(bgp, name);
1627 if (bt)
1628 return bt;
1629
1630 bt = XCALLOC(MTYPE_BMP_TARGETS, sizeof(*bt));
1631 bt->name = XSTRDUP(MTYPE_BMP_TARGETSNAME, name);
1632 bt->bgp = bgp;
1633 bt->bmpbgp = bmp_bgp_get(bgp);
1634 bmp_session_init(&bt->sessions);
1635 bmp_qhash_init(&bt->updhash);
1636 bmp_qlist_init(&bt->updlist);
1637 bmp_actives_init(&bt->actives);
1638 bmp_listeners_init(&bt->listeners);
1639
1640 QOBJ_REG(bt, bmp_targets);
1641 bmp_targets_add(&bt->bmpbgp->targets, bt);
1642 return bt;
1643 }
1644
1645 static void bmp_targets_put(struct bmp_targets *bt)
1646 {
1647 struct bmp *bmp;
1648 struct bmp_active *ba;
1649
1650 THREAD_OFF(bt->t_stats);
1651
1652 frr_each_safe (bmp_actives, &bt->actives, ba)
1653 bmp_active_put(ba);
1654
1655 frr_each_safe(bmp_session, &bt->sessions, bmp) {
1656 bmp_close(bmp);
1657 bmp_free(bmp);
1658 }
1659
1660 bmp_targets_del(&bt->bmpbgp->targets, bt);
1661 QOBJ_UNREG(bt);
1662
1663 bmp_listeners_fini(&bt->listeners);
1664 bmp_actives_fini(&bt->actives);
1665 bmp_qhash_fini(&bt->updhash);
1666 bmp_qlist_fini(&bt->updlist);
1667
1668 XFREE(MTYPE_BMP_ACLNAME, bt->acl_name);
1669 XFREE(MTYPE_BMP_ACLNAME, bt->acl6_name);
1670 bmp_session_fini(&bt->sessions);
1671
1672 XFREE(MTYPE_BMP_TARGETSNAME, bt->name);
1673 XFREE(MTYPE_BMP_TARGETS, bt);
1674 }
1675
1676 static struct bmp_listener *bmp_listener_find(struct bmp_targets *bt,
1677 const union sockunion *su,
1678 int port)
1679 {
1680 struct bmp_listener dummy;
1681 dummy.addr = *su;
1682 dummy.port = port;
1683 return bmp_listeners_find(&bt->listeners, &dummy);
1684 }
1685
1686 static struct bmp_listener *bmp_listener_get(struct bmp_targets *bt,
1687 const union sockunion *su,
1688 int port)
1689 {
1690 struct bmp_listener *bl = bmp_listener_find(bt, su, port);
1691
1692 if (bl)
1693 return bl;
1694
1695 bl = XCALLOC(MTYPE_BMP_LISTENER, sizeof(*bl));
1696 bl->targets = bt;
1697 bl->addr = *su;
1698 bl->port = port;
1699 bl->sock = -1;
1700
1701 bmp_listeners_add(&bt->listeners, bl);
1702 return bl;
1703 }
1704
1705 static void bmp_listener_start(struct bmp_listener *bl)
1706 {
1707 int sock, ret;
1708
1709 sock = socket(bl->addr.sa.sa_family, SOCK_STREAM, 0);
1710 if (sock < 0)
1711 return;
1712
1713 sockopt_reuseaddr(sock);
1714 sockopt_reuseport(sock);
1715 sockopt_v6only(bl->addr.sa.sa_family, sock);
1716 set_cloexec(sock);
1717
1718 ret = sockunion_bind(sock, &bl->addr, bl->port, &bl->addr);
1719 if (ret < 0)
1720 goto out_sock;
1721
1722 ret = listen(sock, 3);
1723 if (ret < 0)
1724 goto out_sock;
1725
1726 bl->sock = sock;
1727 thread_add_read(bm->master, bmp_accept, bl, sock, &bl->t_accept);
1728 return;
1729 out_sock:
1730 close(sock);
1731 }
1732
1733 static void bmp_listener_stop(struct bmp_listener *bl)
1734 {
1735 THREAD_OFF(bl->t_accept);
1736
1737 if (bl->sock != -1)
1738 close(bl->sock);
1739 bl->sock = -1;
1740 }
1741
1742 static struct bmp_active *bmp_active_find(struct bmp_targets *bt,
1743 const char *hostname, int port)
1744 {
1745 struct bmp_active dummy;
1746 dummy.hostname = (char *)hostname;
1747 dummy.port = port;
1748 return bmp_actives_find(&bt->actives, &dummy);
1749 }
1750
1751 static struct bmp_active *bmp_active_get(struct bmp_targets *bt,
1752 const char *hostname, int port)
1753 {
1754 struct bmp_active *ba;
1755
1756 ba = bmp_active_find(bt, hostname, port);
1757 if (ba)
1758 return ba;
1759
1760 ba = XCALLOC(MTYPE_BMP_ACTIVE, sizeof(*ba));
1761 ba->targets = bt;
1762 ba->hostname = XSTRDUP(MTYPE_TMP, hostname);
1763 ba->port = port;
1764 ba->minretry = BMP_DFLT_MINRETRY;
1765 ba->maxretry = BMP_DFLT_MAXRETRY;
1766 ba->socket = -1;
1767
1768 bmp_actives_add(&bt->actives, ba);
1769 return ba;
1770 }
1771
1772 static void bmp_active_put(struct bmp_active *ba)
1773 {
1774 THREAD_OFF(ba->t_timer);
1775 THREAD_OFF(ba->t_read);
1776 THREAD_OFF(ba->t_write);
1777
1778 bmp_actives_del(&ba->targets->actives, ba);
1779
1780 if (ba->bmp) {
1781 ba->bmp->active = NULL;
1782 bmp_close(ba->bmp);
1783 bmp_free(ba->bmp);
1784 }
1785 if (ba->socket != -1)
1786 close(ba->socket);
1787
1788 XFREE(MTYPE_TMP, ba->ifsrc);
1789 XFREE(MTYPE_TMP, ba->hostname);
1790 XFREE(MTYPE_BMP_ACTIVE, ba);
1791 }
1792
1793 static void bmp_active_setup(struct bmp_active *ba);
1794
1795 static void bmp_active_connect(struct bmp_active *ba)
1796 {
1797 enum connect_result res;
1798 struct interface *ifp;
1799 vrf_id_t vrf_id = VRF_DEFAULT;
1800 int res_bind;
1801
1802 for (; ba->addrpos < ba->addrtotal; ba->addrpos++) {
1803 if (ba->ifsrc) {
1804 if (ba->targets && ba->targets->bgp)
1805 vrf_id = ba->targets->bgp->vrf_id;
1806
1807 /* find interface and related */
1808 /* address with same family */
1809 ifp = if_lookup_by_name(ba->ifsrc, vrf_id);
1810 if (!ifp) {
1811 zlog_warn("bmp[%s]: failed to find interface",
1812 ba->ifsrc);
1813 continue;
1814 }
1815
1816 if (bgp_update_address(ifp, &ba->addrs[ba->addrpos],
1817 &ba->addrsrc)){
1818 zlog_warn("bmp[%s]: failed to find matching address",
1819 ba->ifsrc);
1820 continue;
1821 }
1822 zlog_info("bmp[%s]: selected source address : %pSU",
1823 ba->ifsrc, &ba->addrsrc);
1824 }
1825
1826 ba->socket = sockunion_socket(&ba->addrs[ba->addrpos]);
1827 if (ba->socket < 0) {
1828 zlog_warn("bmp[%s]: failed to create socket",
1829 ba->hostname);
1830 continue;
1831 }
1832
1833 set_nonblocking(ba->socket);
1834
1835 if (!sockunion_is_null(&ba->addrsrc)) {
1836 res_bind = sockunion_bind(ba->socket, &ba->addrsrc, 0,
1837 &ba->addrsrc);
1838 if (res_bind < 0) {
1839 zlog_warn(
1840 "bmp[%s]: no bind currently to source address %pSU:%d",
1841 ba->hostname, &ba->addrsrc, ba->port);
1842 close(ba->socket);
1843 ba->socket = -1;
1844 sockunion_init(&ba->addrsrc);
1845 continue;
1846 }
1847 }
1848
1849
1850 res = sockunion_connect(ba->socket, &ba->addrs[ba->addrpos],
1851 htons(ba->port), 0);
1852 switch (res) {
1853 case connect_error:
1854 zlog_warn("bmp[%s]: failed to connect to %pSU:%d",
1855 ba->hostname, &ba->addrs[ba->addrpos],
1856 ba->port);
1857 close(ba->socket);
1858 ba->socket = -1;
1859 sockunion_init(&ba->addrsrc);
1860 continue;
1861 case connect_success:
1862 zlog_info("bmp[%s]: connected to %pSU:%d",
1863 ba->hostname, &ba->addrs[ba->addrpos],
1864 ba->port);
1865 break;
1866 case connect_in_progress:
1867 zlog_warn("bmp[%s]: connect in progress %pSU:%d",
1868 ba->hostname, &ba->addrs[ba->addrpos],
1869 ba->port);
1870 bmp_active_setup(ba);
1871 return;
1872 }
1873 }
1874
1875 /* exhausted all addresses */
1876 ba->curretry += ba->curretry / 2;
1877 bmp_active_setup(ba);
1878 }
1879
1880 static void bmp_active_resolved(struct resolver_query *resq, const char *errstr,
1881 int numaddrs, union sockunion *addr)
1882 {
1883 struct bmp_active *ba = container_of(resq, struct bmp_active, resq);
1884 unsigned i;
1885
1886 if (numaddrs <= 0) {
1887 zlog_warn("bmp[%s]: hostname resolution failed: %s",
1888 ba->hostname, errstr);
1889 ba->last_err = errstr;
1890 ba->curretry += ba->curretry / 2;
1891 ba->addrpos = 0;
1892 ba->addrtotal = 0;
1893 bmp_active_setup(ba);
1894 return;
1895 }
1896
1897 if (numaddrs > (int)array_size(ba->addrs))
1898 numaddrs = array_size(ba->addrs);
1899
1900 ba->addrpos = 0;
1901 ba->addrtotal = numaddrs;
1902 for (i = 0; i < ba->addrtotal; i++)
1903 memcpy(&ba->addrs[i], &addr[i], sizeof(ba->addrs[0]));
1904
1905 bmp_active_connect(ba);
1906 }
1907
1908 static void bmp_active_thread(struct thread *t)
1909 {
1910 struct bmp_active *ba = THREAD_ARG(t);
1911 socklen_t slen;
1912 int status, ret;
1913 vrf_id_t vrf_id;
1914
1915 /* all 3 end up here, though only timer or read+write are active
1916 * at a time */
1917 THREAD_OFF(ba->t_timer);
1918 THREAD_OFF(ba->t_read);
1919 THREAD_OFF(ba->t_write);
1920
1921 ba->last_err = NULL;
1922
1923 if (ba->socket == -1) {
1924 /* get vrf_id */
1925 if (!ba->targets || !ba->targets->bgp)
1926 vrf_id = VRF_DEFAULT;
1927 else
1928 vrf_id = ba->targets->bgp->vrf_id;
1929 resolver_resolve(&ba->resq, AF_UNSPEC, vrf_id, ba->hostname,
1930 bmp_active_resolved);
1931 return;
1932 }
1933
1934 slen = sizeof(status);
1935 ret = getsockopt(ba->socket, SOL_SOCKET, SO_ERROR, (void *)&status,
1936 &slen);
1937
1938 if (ret < 0 || status != 0) {
1939 ba->last_err = strerror(status);
1940 zlog_warn("bmp[%s]: failed to connect to %pSU:%d: %s",
1941 ba->hostname, &ba->addrs[ba->addrpos], ba->port,
1942 ba->last_err);
1943 goto out_next;
1944 }
1945
1946 zlog_warn("bmp[%s]: outbound connection to %pSU:%d", ba->hostname,
1947 &ba->addrs[ba->addrpos], ba->port);
1948
1949 ba->bmp = bmp_open(ba->targets, ba->socket);
1950 if (!ba->bmp)
1951 goto out_next;
1952
1953 ba->bmp->active = ba;
1954 ba->socket = -1;
1955 ba->curretry = ba->minretry;
1956 return;
1957
1958 out_next:
1959 close(ba->socket);
1960 ba->socket = -1;
1961 ba->addrpos++;
1962 bmp_active_connect(ba);
1963 }
1964
1965 static void bmp_active_disconnected(struct bmp_active *ba)
1966 {
1967 ba->bmp = NULL;
1968 bmp_active_setup(ba);
1969 }
1970
1971 static void bmp_active_setup(struct bmp_active *ba)
1972 {
1973 THREAD_OFF(ba->t_timer);
1974 THREAD_OFF(ba->t_read);
1975 THREAD_OFF(ba->t_write);
1976
1977 if (ba->bmp)
1978 return;
1979 if (ba->resq.callback)
1980 return;
1981
1982 if (ba->curretry > ba->maxretry)
1983 ba->curretry = ba->maxretry;
1984
1985 if (ba->socket == -1)
1986 thread_add_timer_msec(bm->master, bmp_active_thread, ba,
1987 ba->curretry, &ba->t_timer);
1988 else {
1989 thread_add_read(bm->master, bmp_active_thread, ba, ba->socket,
1990 &ba->t_read);
1991 thread_add_write(bm->master, bmp_active_thread, ba, ba->socket,
1992 &ba->t_write);
1993 }
1994 }
1995
1996 static struct cmd_node bmp_node = {
1997 .name = "bmp",
1998 .node = BMP_NODE,
1999 .parent_node = BGP_NODE,
2000 .prompt = "%s(config-bgp-bmp)# "
2001 };
2002
2003 static void bmp_targets_autocomplete(vector comps, struct cmd_token *token)
2004 {
2005 struct bgp *bgp;
2006 struct bmp_targets *target;
2007 struct listnode *node;
2008
2009 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
2010 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
2011
2012 if (!bmpbgp)
2013 continue;
2014
2015 frr_each_safe (bmp_targets, &bmpbgp->targets, target)
2016 vector_set(comps,
2017 XSTRDUP(MTYPE_COMPLETION, target->name));
2018 }
2019 }
2020
2021 static const struct cmd_variable_handler bmp_targets_var_handlers[] = {
2022 {.tokenname = "BMPTARGETS", .completions = bmp_targets_autocomplete},
2023 {.completions = NULL}};
2024
2025 #define BMP_STR "BGP Monitoring Protocol\n"
2026
2027 #ifndef VTYSH_EXTRACT_PL
2028 #include "bgpd/bgp_bmp_clippy.c"
2029 #endif
2030
2031 DEFPY_NOSH(bmp_targets_main,
2032 bmp_targets_cmd,
2033 "bmp targets BMPTARGETS",
2034 BMP_STR
2035 "Create BMP target group\n"
2036 "Name of the BMP target group\n")
2037 {
2038 VTY_DECLVAR_CONTEXT(bgp, bgp);
2039 struct bmp_targets *bt;
2040
2041 bt = bmp_targets_get(bgp, bmptargets);
2042
2043 VTY_PUSH_CONTEXT_SUB(BMP_NODE, bt);
2044 return CMD_SUCCESS;
2045 }
2046
2047 DEFPY(no_bmp_targets_main,
2048 no_bmp_targets_cmd,
2049 "no bmp targets BMPTARGETS",
2050 NO_STR
2051 BMP_STR
2052 "Delete BMP target group\n"
2053 "Name of the BMP target group\n")
2054 {
2055 VTY_DECLVAR_CONTEXT(bgp, bgp);
2056 struct bmp_targets *bt;
2057
2058 bt = bmp_targets_find1(bgp, bmptargets);
2059 if (!bt) {
2060 vty_out(vty, "%% BMP target group not found\n");
2061 return CMD_WARNING;
2062 }
2063 bmp_targets_put(bt);
2064 return CMD_SUCCESS;
2065 }
2066
2067 DEFPY(bmp_listener_main,
2068 bmp_listener_cmd,
2069 "bmp listener <X:X::X:X|A.B.C.D> port (1-65535)",
2070 BMP_STR
2071 "Listen for inbound BMP connections\n"
2072 "IPv6 address to listen on\n"
2073 "IPv4 address to listen on\n"
2074 "TCP Port number\n"
2075 "TCP Port number\n")
2076 {
2077 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2078 struct bmp_listener *bl;
2079
2080 bl = bmp_listener_get(bt, listener, port);
2081 if (bl->sock == -1)
2082 bmp_listener_start(bl);
2083
2084 return CMD_SUCCESS;
2085 }
2086
2087 DEFPY(no_bmp_listener_main,
2088 no_bmp_listener_cmd,
2089 "no bmp listener <X:X::X:X|A.B.C.D> port (1-65535)",
2090 NO_STR
2091 BMP_STR
2092 "Create BMP listener\n"
2093 "IPv6 address to listen on\n"
2094 "IPv4 address to listen on\n"
2095 "TCP Port number\n"
2096 "TCP Port number\n")
2097 {
2098 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2099 struct bmp_listener *bl;
2100
2101 bl = bmp_listener_find(bt, listener, port);
2102 if (!bl) {
2103 vty_out(vty, "%% BMP listener not found\n");
2104 return CMD_WARNING;
2105 }
2106 bmp_listener_stop(bl);
2107 bmp_listener_put(bl);
2108 return CMD_SUCCESS;
2109 }
2110
2111 DEFPY(bmp_connect,
2112 bmp_connect_cmd,
2113 "[no] bmp connect HOSTNAME port (1-65535) {min-retry (100-86400000)|max-retry (100-86400000)} [source-interface <WORD$srcif>]",
2114 NO_STR
2115 BMP_STR
2116 "Actively establish connection to monitoring station\n"
2117 "Monitoring station hostname or address\n"
2118 "TCP port\n"
2119 "TCP port\n"
2120 "Minimum connection retry interval\n"
2121 "Minimum connection retry interval (milliseconds)\n"
2122 "Maximum connection retry interval\n"
2123 "Maximum connection retry interval (milliseconds)\n"
2124 "Source interface to use\n"
2125 "Define an interface\n")
2126 {
2127 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2128 struct bmp_active *ba;
2129
2130 if (no) {
2131 ba = bmp_active_find(bt, hostname, port);
2132 if (!ba) {
2133 vty_out(vty, "%% No such active connection found\n");
2134 return CMD_WARNING;
2135 }
2136 /* connection deletion need same hostname port and interface */
2137 if (ba->ifsrc || srcif)
2138 if ((!ba->ifsrc) || (!srcif) ||
2139 !strcmp(ba->ifsrc, srcif)) {
2140 vty_out(vty,
2141 "%% No such active connection found\n");
2142 return CMD_WARNING;
2143 }
2144 bmp_active_put(ba);
2145 return CMD_SUCCESS;
2146 }
2147
2148 ba = bmp_active_get(bt, hostname, port);
2149 if (srcif)
2150 ba->ifsrc = XSTRDUP(MTYPE_TMP, srcif);
2151 if (min_retry_str)
2152 ba->minretry = min_retry;
2153 if (max_retry_str)
2154 ba->maxretry = max_retry;
2155 ba->curretry = ba->minretry;
2156 bmp_active_setup(ba);
2157
2158 return CMD_SUCCESS;
2159 }
2160
2161 DEFPY(bmp_acl,
2162 bmp_acl_cmd,
2163 "[no] <ip|ipv6>$af access-list ACCESSLIST_NAME$access_list",
2164 NO_STR
2165 IP_STR
2166 IPV6_STR
2167 "Access list to restrict BMP sessions\n"
2168 "Access list name\n")
2169 {
2170 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2171 char **what;
2172
2173 if (no)
2174 access_list = NULL;
2175 if (!strcmp(af, "ipv6"))
2176 what = &bt->acl6_name;
2177 else
2178 what = &bt->acl_name;
2179
2180 XFREE(MTYPE_BMP_ACLNAME, *what);
2181 if (access_list)
2182 *what = XSTRDUP(MTYPE_BMP_ACLNAME, access_list);
2183
2184 return CMD_SUCCESS;
2185 }
2186
2187 DEFPY(bmp_stats_cfg,
2188 bmp_stats_cmd,
2189 "[no] bmp stats [interval (100-86400000)]",
2190 NO_STR
2191 BMP_STR
2192 "Send BMP statistics messages\n"
2193 "Specify BMP stats interval\n"
2194 "Interval (milliseconds) to send BMP Stats in\n")
2195 {
2196 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2197
2198 THREAD_OFF(bt->t_stats);
2199 if (no)
2200 bt->stat_msec = 0;
2201 else if (interval_str)
2202 bt->stat_msec = interval;
2203 else
2204 bt->stat_msec = BMP_STAT_DEFAULT_TIMER;
2205
2206 if (bt->stat_msec)
2207 thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
2208 &bt->t_stats);
2209 return CMD_SUCCESS;
2210 }
2211
2212 DEFPY(bmp_monitor_cfg,
2213 bmp_monitor_cmd,
2214 "[no] bmp monitor <ipv4|ipv6|l2vpn> <unicast|multicast|evpn|vpn> <pre-policy|post-policy>$policy",
2215 NO_STR
2216 BMP_STR
2217 "Send BMP route monitoring messages\n"
2218 BGP_AF_STR
2219 BGP_AF_STR
2220 BGP_AF_STR
2221 BGP_AF_STR
2222 BGP_AF_STR
2223 BGP_AF_STR
2224 BGP_AF_STR
2225 "Send state before policy and filter processing\n"
2226 "Send state with policy and filters applied\n")
2227 {
2228 int index = 0;
2229 uint8_t flag, prev;
2230 afi_t afi;
2231 safi_t safi;
2232
2233 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2234 struct bmp *bmp;
2235
2236 argv_find_and_parse_afi(argv, argc, &index, &afi);
2237 argv_find_and_parse_safi(argv, argc, &index, &safi);
2238
2239 if (policy[1] == 'r')
2240 flag = BMP_MON_PREPOLICY;
2241 else
2242 flag = BMP_MON_POSTPOLICY;
2243
2244 prev = bt->afimon[afi][safi];
2245 if (no)
2246 bt->afimon[afi][safi] &= ~flag;
2247 else
2248 bt->afimon[afi][safi] |= flag;
2249
2250 if (prev == bt->afimon[afi][safi])
2251 return CMD_SUCCESS;
2252
2253 frr_each (bmp_session, &bt->sessions, bmp) {
2254 if (bmp->syncafi == afi && bmp->syncsafi == safi) {
2255 bmp->syncafi = AFI_MAX;
2256 bmp->syncsafi = SAFI_MAX;
2257 }
2258
2259 if (!bt->afimon[afi][safi]) {
2260 bmp->afistate[afi][safi] = BMP_AFI_INACTIVE;
2261 continue;
2262 }
2263
2264 bmp->afistate[afi][safi] = BMP_AFI_NEEDSYNC;
2265 }
2266
2267 return CMD_SUCCESS;
2268 }
2269
2270 DEFPY(bmp_mirror_cfg,
2271 bmp_mirror_cmd,
2272 "[no] bmp mirror",
2273 NO_STR
2274 BMP_STR
2275 "Send BMP route mirroring messages\n")
2276 {
2277 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2278 struct bmp *bmp;
2279
2280 if (bt->mirror == !no)
2281 return CMD_SUCCESS;
2282
2283 bt->mirror = !no;
2284 if (bt->mirror)
2285 return CMD_SUCCESS;
2286
2287 frr_each (bmp_session, &bt->sessions, bmp) {
2288 struct bmp_mirrorq *bmq;
2289
2290 while ((bmq = bmp_pull_mirror(bmp)))
2291 if (!bmq->refcount)
2292 XFREE(MTYPE_BMP_MIRRORQ, bmq);
2293 }
2294 return CMD_SUCCESS;
2295 }
2296
2297 DEFPY(bmp_mirror_limit_cfg,
2298 bmp_mirror_limit_cmd,
2299 "bmp mirror buffer-limit (0-4294967294)",
2300 BMP_STR
2301 "Route Mirroring settings\n"
2302 "Configure maximum memory used for buffered mirroring messages\n"
2303 "Limit in bytes\n")
2304 {
2305 VTY_DECLVAR_CONTEXT(bgp, bgp);
2306 struct bmp_bgp *bmpbgp;
2307
2308 bmpbgp = bmp_bgp_get(bgp);
2309 bmpbgp->mirror_qsizelimit = buffer_limit;
2310
2311 return CMD_SUCCESS;
2312 }
2313
2314 DEFPY(no_bmp_mirror_limit_cfg,
2315 no_bmp_mirror_limit_cmd,
2316 "no bmp mirror buffer-limit [(0-4294967294)]",
2317 NO_STR
2318 BMP_STR
2319 "Route Mirroring settings\n"
2320 "Configure maximum memory used for buffered mirroring messages\n"
2321 "Limit in bytes\n")
2322 {
2323 VTY_DECLVAR_CONTEXT(bgp, bgp);
2324 struct bmp_bgp *bmpbgp;
2325
2326 bmpbgp = bmp_bgp_get(bgp);
2327 bmpbgp->mirror_qsizelimit = ~0UL;
2328
2329 return CMD_SUCCESS;
2330 }
2331
2332
2333 DEFPY(show_bmp,
2334 show_bmp_cmd,
2335 "show bmp",
2336 SHOW_STR
2337 BMP_STR)
2338 {
2339 struct bmp_bgp *bmpbgp;
2340 struct bmp_targets *bt;
2341 struct bmp_listener *bl;
2342 struct bmp_active *ba;
2343 struct bmp *bmp;
2344 struct ttable *tt;
2345 char uptime[BGP_UPTIME_LEN];
2346 char *out;
2347
2348 frr_each(bmp_bgph, &bmp_bgph, bmpbgp) {
2349 vty_out(vty, "BMP state for BGP %s:\n\n",
2350 bmpbgp->bgp->name_pretty);
2351 vty_out(vty, " Route Mirroring %9zu bytes (%zu messages) pending\n",
2352 bmpbgp->mirror_qsize,
2353 bmp_mirrorq_count(&bmpbgp->mirrorq));
2354 vty_out(vty, " %9zu bytes maximum buffer used\n",
2355 bmpbgp->mirror_qsizemax);
2356 if (bmpbgp->mirror_qsizelimit != ~0UL)
2357 vty_out(vty, " %9zu bytes buffer size limit\n",
2358 bmpbgp->mirror_qsizelimit);
2359 vty_out(vty, "\n");
2360
2361 frr_each(bmp_targets, &bmpbgp->targets, bt) {
2362 vty_out(vty, " Targets \"%s\":\n", bt->name);
2363 vty_out(vty, " Route Mirroring %sabled\n",
2364 bt->mirror ? "en" : "dis");
2365
2366 afi_t afi;
2367 safi_t safi;
2368
2369 FOREACH_AFI_SAFI (afi, safi) {
2370 const char *str = NULL;
2371
2372 switch (bt->afimon[afi][safi]) {
2373 case BMP_MON_PREPOLICY:
2374 str = "pre-policy";
2375 break;
2376 case BMP_MON_POSTPOLICY:
2377 str = "post-policy";
2378 break;
2379 case BMP_MON_PREPOLICY | BMP_MON_POSTPOLICY:
2380 str = "pre-policy and post-policy";
2381 break;
2382 }
2383 if (!str)
2384 continue;
2385 vty_out(vty, " Route Monitoring %s %s %s\n",
2386 afi2str(afi), safi2str(safi), str);
2387 }
2388
2389 vty_out(vty, " Listeners:\n");
2390 frr_each (bmp_listeners, &bt->listeners, bl)
2391 vty_out(vty, " %pSU:%d\n", &bl->addr,
2392 bl->port);
2393
2394 vty_out(vty, "\n Outbound connections:\n");
2395 tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
2396 ttable_add_row(tt, "remote|state||timer|local");
2397 ttable_rowseps(tt, 0, BOTTOM, true, '-');
2398 frr_each (bmp_actives, &bt->actives, ba) {
2399 const char *state_str = "?";
2400
2401 if (ba->bmp) {
2402 peer_uptime(ba->bmp->t_up.tv_sec,
2403 uptime, sizeof(uptime),
2404 false, NULL);
2405 ttable_add_row(tt,
2406 "%s:%d|Up|%s|%s|%pSU",
2407 ba->hostname, ba->port,
2408 ba->bmp->remote, uptime,
2409 &ba->addrsrc);
2410 continue;
2411 }
2412
2413 uptime[0] = '\0';
2414
2415 if (ba->t_timer) {
2416 long trem = thread_timer_remain_second(
2417 ba->t_timer);
2418
2419 peer_uptime(monotime(NULL) - trem,
2420 uptime, sizeof(uptime),
2421 false, NULL);
2422 state_str = "RetryWait";
2423 } else if (ba->t_read) {
2424 state_str = "Connecting";
2425 } else if (ba->resq.callback) {
2426 state_str = "Resolving";
2427 }
2428
2429 ttable_add_row(tt, "%s:%d|%s|%s|%s|%pSU",
2430 ba->hostname, ba->port,
2431 state_str,
2432 ba->last_err ? ba->last_err : "",
2433 uptime, &ba->addrsrc);
2434 continue;
2435 }
2436 out = ttable_dump(tt, "\n");
2437 vty_out(vty, "%s", out);
2438 XFREE(MTYPE_TMP, out);
2439 ttable_del(tt);
2440
2441 vty_out(vty, "\n %zu connected clients:\n",
2442 bmp_session_count(&bt->sessions));
2443 tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
2444 ttable_add_row(tt, "remote|uptime|MonSent|MirrSent|MirrLost|ByteSent|ByteQ|ByteQKernel");
2445 ttable_rowseps(tt, 0, BOTTOM, true, '-');
2446
2447 frr_each (bmp_session, &bt->sessions, bmp) {
2448 uint64_t total;
2449 size_t q, kq;
2450
2451 pullwr_stats(bmp->pullwr, &total, &q, &kq);
2452
2453 peer_uptime(bmp->t_up.tv_sec, uptime,
2454 sizeof(uptime), false, NULL);
2455
2456 ttable_add_row(tt, "%s|%s|%Lu|%Lu|%Lu|%Lu|%zu|%zu",
2457 bmp->remote, uptime,
2458 bmp->cnt_update,
2459 bmp->cnt_mirror,
2460 bmp->cnt_mirror_overruns,
2461 total, q, kq);
2462 }
2463 out = ttable_dump(tt, "\n");
2464 vty_out(vty, "%s", out);
2465 XFREE(MTYPE_TMP, out);
2466 ttable_del(tt);
2467 vty_out(vty, "\n");
2468 }
2469 }
2470
2471 return CMD_SUCCESS;
2472 }
2473
2474 static int bmp_config_write(struct bgp *bgp, struct vty *vty)
2475 {
2476 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
2477 struct bmp_targets *bt;
2478 struct bmp_listener *bl;
2479 struct bmp_active *ba;
2480 afi_t afi;
2481 safi_t safi;
2482
2483 if (!bmpbgp)
2484 return 0;
2485
2486 if (bmpbgp->mirror_qsizelimit != ~0UL)
2487 vty_out(vty, " !\n bmp mirror buffer-limit %zu\n",
2488 bmpbgp->mirror_qsizelimit);
2489
2490 frr_each(bmp_targets, &bmpbgp->targets, bt) {
2491 vty_out(vty, " !\n bmp targets %s\n", bt->name);
2492
2493 if (bt->acl6_name)
2494 vty_out(vty, " ipv6 access-list %s\n", bt->acl6_name);
2495 if (bt->acl_name)
2496 vty_out(vty, " ip access-list %s\n", bt->acl_name);
2497
2498 if (bt->stat_msec)
2499 vty_out(vty, " bmp stats interval %d\n",
2500 bt->stat_msec);
2501
2502 if (bt->mirror)
2503 vty_out(vty, " bmp mirror\n");
2504
2505 FOREACH_AFI_SAFI (afi, safi) {
2506 const char *afi_str = (afi == AFI_IP) ? "ipv4" : "ipv6";
2507
2508 if (bt->afimon[afi][safi] & BMP_MON_PREPOLICY)
2509 vty_out(vty, " bmp monitor %s %s pre-policy\n",
2510 afi_str, safi2str(safi));
2511 if (bt->afimon[afi][safi] & BMP_MON_POSTPOLICY)
2512 vty_out(vty, " bmp monitor %s %s post-policy\n",
2513 afi_str, safi2str(safi));
2514 }
2515 frr_each (bmp_listeners, &bt->listeners, bl)
2516 vty_out(vty, " \n bmp listener %pSU port %d\n",
2517 &bl->addr, bl->port);
2518
2519 frr_each (bmp_actives, &bt->actives, ba) {
2520 vty_out(vty, " bmp connect %s port %u min-retry %u max-retry %u",
2521 ba->hostname, ba->port,
2522 ba->minretry, ba->maxretry);
2523
2524 if (ba->ifsrc)
2525 vty_out(vty, " source-interface %s\n", ba->ifsrc);
2526 else
2527 vty_out(vty, "\n");
2528 }
2529 vty_out(vty, " exit\n");
2530 }
2531
2532 return 0;
2533 }
2534
2535 static int bgp_bmp_init(struct thread_master *tm)
2536 {
2537 install_node(&bmp_node);
2538 install_default(BMP_NODE);
2539
2540 cmd_variable_handler_register(bmp_targets_var_handlers);
2541
2542 install_element(BGP_NODE, &bmp_targets_cmd);
2543 install_element(BGP_NODE, &no_bmp_targets_cmd);
2544
2545 install_element(BMP_NODE, &bmp_listener_cmd);
2546 install_element(BMP_NODE, &no_bmp_listener_cmd);
2547 install_element(BMP_NODE, &bmp_connect_cmd);
2548 install_element(BMP_NODE, &bmp_acl_cmd);
2549 install_element(BMP_NODE, &bmp_stats_cmd);
2550 install_element(BMP_NODE, &bmp_monitor_cmd);
2551 install_element(BMP_NODE, &bmp_mirror_cmd);
2552
2553 install_element(BGP_NODE, &bmp_mirror_limit_cmd);
2554 install_element(BGP_NODE, &no_bmp_mirror_limit_cmd);
2555
2556 install_element(VIEW_NODE, &show_bmp_cmd);
2557
2558 resolver_init(tm);
2559 return 0;
2560 }
2561
2562 static int bgp_bmp_module_init(void)
2563 {
2564 hook_register(bgp_packet_dump, bmp_mirror_packet);
2565 hook_register(bgp_packet_send, bmp_outgoing_packet);
2566 hook_register(peer_status_changed, bmp_peer_status_changed);
2567 hook_register(peer_backward_transition, bmp_peer_backward);
2568 hook_register(bgp_process, bmp_process);
2569 hook_register(bgp_inst_config_write, bmp_config_write);
2570 hook_register(bgp_inst_delete, bmp_bgp_del);
2571 hook_register(frr_late_init, bgp_bmp_init);
2572 return 0;
2573 }
2574
2575 FRR_MODULE_SETUP(.name = "bgpd_bmp", .version = FRR_VERSION,
2576 .description = "bgpd BMP module",
2577 .init = bgp_bmp_module_init,
2578 );