+// SPDX-License-Identifier: GPL-2.0-or-later
/* BMP support.
* Copyright (C) 2018 Yasuhiro Ohara
* Copyright (C) 2019 David Lamparter for NetDEF, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "sockunion.h"
#include "command.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "queue.h"
#include "pullwr.h"
/* Local Port, Remote Port */
if (peer->su_local->sa.sa_family == AF_INET6)
- stream_putw(s, peer->su_local->sin6.sin6_port);
+ stream_putw(s, htons(peer->su_local->sin6.sin6_port));
else if (peer->su_local->sa.sa_family == AF_INET)
- stream_putw(s, peer->su_local->sin.sin_port);
+ stream_putw(s, htons(peer->su_local->sin.sin_port));
if (peer->su_remote->sa.sa_family == AF_INET6)
- stream_putw(s, peer->su_remote->sin6.sin6_port);
+ stream_putw(s, htons(peer->su_remote->sin6.sin6_port));
else if (peer->su_remote->sa.sa_family == AF_INET)
- stream_putw(s, peer->su_remote->sin.sin_port);
+ stream_putw(s, htons(peer->su_remote->sin.sin_port));
static const uint8_t dummy_open[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
stream_putw(s, 0);
/* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
- total_attr_len = bgp_packet_attribute(NULL, peer, s, attr,
- &vecarr, NULL, afi, safi, peer, NULL, NULL, 0, 0, 0);
+ total_attr_len =
+ bgp_packet_attribute(NULL, peer, s, attr, &vecarr, NULL, afi,
+ safi, peer, NULL, NULL, 0, 0, 0, NULL);
/* space check? */
}
struct bgp_table *table = bmp->targets->bgp->rib[afi][safi];
- struct bgp_dest *bn;
+ struct bgp_dest *bn = NULL;
struct bgp_path_info *bpi = NULL, *bpiter;
struct bgp_adj_in *adjin = NULL, *adjiter;
bmp_monitor(bmp, adjin->peer, 0, bn_p, prd, adjin->attr, afi,
safi, adjin->uptime);
+ if (bn)
+ bgp_dest_unlock_node(bn);
+
return true;
}
{
struct bmp_queue_entry *bqe;
struct peer *peer;
- struct bgp_dest *bn;
+ struct bgp_dest *bn = NULL;
bool written = false;
bqe = bmp_pull(bmp);
if (!peer_established(peer))
goto out;
- bn = bgp_node_lookup(bmp->targets->bgp->rib[afi][safi], &bqe->p);
- struct prefix_rd *prd = NULL;
- if ((bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) ||
- (bqe->safi == SAFI_MPLS_VPN))
- prd = &bqe->rd;
+ bool is_vpn = (bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) ||
+ (bqe->safi == SAFI_MPLS_VPN);
+
+ struct prefix_rd *prd = is_vpn ? &bqe->rd : NULL;
+ bn = bgp_safi_node_lookup(bmp->targets->bgp->rib[afi][safi], safi,
+ &bqe->p, prd);
+
if (bmp->targets->afimon[afi][safi] & BMP_MON_POSTPOLICY) {
struct bgp_path_info *bpi;
out:
if (!bqe->refcount)
XFREE(MTYPE_BMP_QUEUE, bqe);
+
+ if (bn)
+ bgp_dest_unlock_node(bn);
+
return written;
}
(*cnt)++;
}
-static void bmp_stats(struct thread *thread)
+static void bmp_stats(struct event *thread)
{
- struct bmp_targets *bt = THREAD_ARG(thread);
+ struct bmp_targets *bt = EVENT_ARG(thread);
struct stream *s;
struct peer *peer;
struct listnode *node;
struct timeval tv;
if (bt->stat_msec)
- thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
- &bt->t_stats);
+ event_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
+ &bt->t_stats);
gettimeofday(&tv, NULL);
}
/* read from the BMP socket to detect session termination */
-static void bmp_read(struct thread *t)
+static void bmp_read(struct event *t)
{
- struct bmp *bmp = THREAD_ARG(t);
+ struct bmp *bmp = EVENT_ARG(t);
char buf[1024];
ssize_t n;
return;
}
- thread_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read);
+ event_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read);
}
static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock)
bmp->state = BMP_PeerUp;
bmp->pullwr = pullwr_new(bm->master, bmp_sock, bmp, bmp_wrfill,
bmp_wrerr);
- thread_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read);
+ event_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read);
bmp_send_initiation(bmp);
return bmp;
}
/* Accept BMP connection. */
-static void bmp_accept(struct thread *thread)
+static void bmp_accept(struct event *thread)
{
union sockunion su;
- struct bmp_listener *bl = THREAD_ARG(thread);
+ struct bmp_listener *bl = EVENT_ARG(thread);
int bmp_sock;
/* We continue hearing BMP socket. */
- thread_add_read(bm->master, bmp_accept, bl, bl->sock, &bl->t_accept);
+ event_add_read(bm->master, bmp_accept, bl, bl->sock, &bl->t_accept);
memset(&su, 0, sizeof(union sockunion));
struct bmp_queue_entry *bqe;
struct bmp_mirrorq *bmq;
- THREAD_OFF(bmp->t_read);
+ EVENT_OFF(bmp->t_read);
if (bmp->active)
bmp_active_disconnected(bmp->active);
if (!bqe->refcount)
XFREE(MTYPE_BMP_QUEUE, bqe);
- THREAD_OFF(bmp->t_read);
+ EVENT_OFF(bmp->t_read);
pullwr_del(bmp->pullwr);
close(bmp->socket);
}
struct bmp *bmp;
struct bmp_active *ba;
- THREAD_OFF(bt->t_stats);
+ EVENT_OFF(bt->t_stats);
frr_each_safe (bmp_actives, &bt->actives, ba)
bmp_active_put(ba);
goto out_sock;
bl->sock = sock;
- thread_add_read(bm->master, bmp_accept, bl, sock, &bl->t_accept);
+ event_add_read(bm->master, bmp_accept, bl, sock, &bl->t_accept);
return;
out_sock:
close(sock);
static void bmp_listener_stop(struct bmp_listener *bl)
{
- THREAD_OFF(bl->t_accept);
+ EVENT_OFF(bl->t_accept);
if (bl->sock != -1)
close(bl->sock);
static void bmp_active_put(struct bmp_active *ba)
{
- THREAD_OFF(ba->t_timer);
- THREAD_OFF(ba->t_read);
- THREAD_OFF(ba->t_write);
+ EVENT_OFF(ba->t_timer);
+ EVENT_OFF(ba->t_read);
+ EVENT_OFF(ba->t_write);
bmp_actives_del(&ba->targets->actives, ba);
bmp_active_connect(ba);
}
-static void bmp_active_thread(struct thread *t)
+static void bmp_active_thread(struct event *t)
{
- struct bmp_active *ba = THREAD_ARG(t);
+ struct bmp_active *ba = EVENT_ARG(t);
socklen_t slen;
int status, ret;
vrf_id_t vrf_id;
/* all 3 end up here, though only timer or read+write are active
* at a time */
- THREAD_OFF(ba->t_timer);
- THREAD_OFF(ba->t_read);
- THREAD_OFF(ba->t_write);
+ EVENT_OFF(ba->t_timer);
+ EVENT_OFF(ba->t_read);
+ EVENT_OFF(ba->t_write);
ba->last_err = NULL;
static void bmp_active_setup(struct bmp_active *ba)
{
- THREAD_OFF(ba->t_timer);
- THREAD_OFF(ba->t_read);
- THREAD_OFF(ba->t_write);
+ EVENT_OFF(ba->t_timer);
+ EVENT_OFF(ba->t_read);
+ EVENT_OFF(ba->t_write);
if (ba->bmp)
return;
ba->curretry = ba->maxretry;
if (ba->socket == -1)
- thread_add_timer_msec(bm->master, bmp_active_thread, ba,
- ba->curretry, &ba->t_timer);
+ event_add_timer_msec(bm->master, bmp_active_thread, ba,
+ ba->curretry, &ba->t_timer);
else {
- thread_add_read(bm->master, bmp_active_thread, ba, ba->socket,
- &ba->t_read);
- thread_add_write(bm->master, bmp_active_thread, ba, ba->socket,
+ event_add_read(bm->master, bmp_active_thread, ba, ba->socket,
+ &ba->t_read);
+ event_add_write(bm->master, bmp_active_thread, ba, ba->socket,
&ba->t_write);
}
}
#define BMP_STR "BGP Monitoring Protocol\n"
-#ifndef VTYSH_EXTRACT_PL
#include "bgpd/bgp_bmp_clippy.c"
-#endif
DEFPY_NOSH(bmp_targets_main,
bmp_targets_cmd,
{
VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
- THREAD_OFF(bt->t_stats);
+ EVENT_OFF(bt->t_stats);
if (no)
bt->stat_msec = 0;
else if (interval_str)
bt->stat_msec = BMP_STAT_DEFAULT_TIMER;
if (bt->stat_msec)
- thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
- &bt->t_stats);
+ event_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
+ &bt->t_stats);
return CMD_SUCCESS;
}
uptime[0] = '\0';
if (ba->t_timer) {
- long trem = thread_timer_remain_second(
+ long trem = event_timer_remain_second(
ba->t_timer);
peer_uptime(monotime(NULL) - trem,
vty_out(vty, " bmp mirror\n");
FOREACH_AFI_SAFI (afi, safi) {
- const char *afi_str = (afi == AFI_IP) ? "ipv4" : "ipv6";
-
if (bt->afimon[afi][safi] & BMP_MON_PREPOLICY)
vty_out(vty, " bmp monitor %s %s pre-policy\n",
- afi_str, safi2str(safi));
+ afi2str_lower(afi), safi2str(safi));
if (bt->afimon[afi][safi] & BMP_MON_POSTPOLICY)
- vty_out(vty, " bmp monitor %s %s post-policy\n",
- afi_str, safi2str(safi));
+ vty_out(vty,
+ " bmp monitor %s %s post-policy\n",
+ afi2str_lower(afi), safi2str(safi));
}
frr_each (bmp_listeners, &bt->listeners, bl)
vty_out(vty, " \n bmp listener %pSU port %d\n",
return 0;
}
-static int bgp_bmp_init(struct thread_master *tm)
+static int bgp_bmp_init(struct event_loop *tm)
{
install_node(&bmp_node);
install_default(BMP_NODE);