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