]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_bmp.c
Merge pull request #12837 from donaldsharp/unlikely_routemap
[mirror_frr.git] / bgpd / bgp_bmp.c
index cf196f7390af3cf6452e24bde03e45a0a452574c..baf164679c725586c871eaaa0c7df7e46d2e4037 100644 (file)
@@ -1,20 +1,7 @@
+// 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>
@@ -24,7 +11,7 @@
 #include "sockunion.h"
 #include "command.h"
 #include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
 #include "linklist.h"
 #include "queue.h"
 #include "pullwr.h"
@@ -402,13 +389,13 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down)
 
                /* 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,
@@ -853,8 +840,9 @@ static struct stream *bmp_update(const struct prefix *p, struct prefix_rd *prd,
        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? */
 
@@ -992,7 +980,7 @@ afibreak:
        }
 
        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;
 
@@ -1120,6 +1108,9 @@ afibreak:
                bmp_monitor(bmp, adjin->peer, 0, bn_p, prd, adjin->attr, afi,
                            safi, adjin->uptime);
 
+       if (bn)
+               bgp_dest_unlock_node(bn);
+
        return true;
 }
 
@@ -1145,7 +1136,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr)
 {
        struct bmp_queue_entry *bqe;
        struct peer *peer;
-       struct bgp_dest *bn;
+       struct bgp_dest *bn = NULL;
        bool written = false;
 
        bqe = bmp_pull(bmp);
@@ -1180,11 +1171,13 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr)
        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;
@@ -1220,6 +1213,10 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr)
 out:
        if (!bqe->refcount)
                XFREE(MTYPE_BMP_QUEUE, bqe);
+
+       if (bn)
+               bgp_dest_unlock_node(bn);
+
        return written;
 }
 
@@ -1338,17 +1335,17 @@ static void bmp_stat_put_u32(struct stream *s, size_t *cnt, uint16_t type,
        (*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);
 
@@ -1391,9 +1388,9 @@ static void bmp_stats(struct thread *thread)
 }
 
 /* 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;
 
@@ -1412,7 +1409,7 @@ static void bmp_read(struct thread *t)
                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)
@@ -1488,21 +1485,21 @@ 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));
 
@@ -1520,7 +1517,7 @@ static void bmp_close(struct bmp *bmp)
        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);
@@ -1532,7 +1529,7 @@ static void bmp_close(struct bmp *bmp)
                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);
 }
@@ -1647,7 +1644,7 @@ static void bmp_targets_put(struct bmp_targets *bt)
        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);
@@ -1724,7 +1721,7 @@ static void bmp_listener_start(struct bmp_listener *bl)
                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);
@@ -1732,7 +1729,7 @@ out_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);
@@ -1771,9 +1768,9 @@ static struct bmp_active *bmp_active_get(struct bmp_targets *bt,
 
 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);
 
@@ -1905,18 +1902,18 @@ static void bmp_active_resolved(struct resolver_query *resq, const char *errstr,
        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;
 
@@ -1970,9 +1967,9 @@ static void bmp_active_disconnected(struct bmp_active *ba)
 
 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;
@@ -1983,12 +1980,12 @@ static void bmp_active_setup(struct bmp_active *ba)
                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);
        }
 }
@@ -2024,9 +2021,7 @@ static const struct cmd_variable_handler bmp_targets_var_handlers[] = {
 
 #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,
@@ -2195,7 +2190,7 @@ DEFPY(bmp_stats_cfg,
 {
        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)
@@ -2204,8 +2199,8 @@ DEFPY(bmp_stats_cfg,
                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;
 }
 
@@ -2413,7 +2408,7 @@ DEFPY(show_bmp,
                                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,
@@ -2503,14 +2498,13 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
                        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",
@@ -2532,7 +2526,7 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
        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);