]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_bmp.c
Merge pull request #5703 from ton31337/feature/limit_outgoing_prefixes
[mirror_frr.git] / bgpd / bgp_bmp.c
index ff655048a8cd4fb94608b6b205f0c0a5405ed1dc..24a9cab5d150f4dfe56963d9739c9b6f699118b8 100644 (file)
@@ -1307,8 +1307,12 @@ static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock)
        }
        bt->cnt_accept++;
 
-       setsockopt(bmp_sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
-       setsockopt(bmp_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+       if (setsockopt(bmp_sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
+               flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt SO_KEEPALIVE: %s(%d)",
+                        bmp_sock, safe_strerror(errno), errno);
+       if (setsockopt(bmp_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
+               flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt TCP_NODELAY: %s(%d)",
+                        bmp_sock, safe_strerror(errno), errno);
 
        zlog_info("bmp[%s] connection established", buf);
 
@@ -1658,18 +1662,23 @@ static void bmp_active_connect(struct bmp_active *ba)
        bmp_active_setup(ba);
 }
 
-static void bmp_active_resolved(struct resolver_query *resq, int numaddrs,
-                               union sockunion *addr)
+static void bmp_active_resolved(struct resolver_query *resq, const char *errstr,
+                               int numaddrs, union sockunion *addr)
 {
        struct bmp_active *ba = container_of(resq, struct bmp_active, resq);
        unsigned i;
 
        if (numaddrs <= 0) {
-               zlog_warn("bmp[%s]: hostname resolution failed", ba->hostname);
+               zlog_warn("bmp[%s]: hostname resolution failed: %s",
+                         ba->hostname, errstr);
+               ba->last_err = errstr;
                ba->curretry += ba->curretry / 2;
+               ba->addrpos = 0;
+               ba->addrtotal = 0;
                bmp_active_setup(ba);
                return;
        }
+
        if (numaddrs > (int)array_size(ba->addrs))
                numaddrs = array_size(ba->addrs);
 
@@ -1694,6 +1703,8 @@ static int bmp_active_thread(struct thread *t)
        THREAD_OFF(ba->t_read);
        THREAD_OFF(ba->t_write);
 
+       ba->last_err = NULL;
+
        if (ba->socket == -1) {
                resolver_resolve(&ba->resq, AF_UNSPEC, ba->hostname,
                                 bmp_active_resolved);
@@ -1706,8 +1717,9 @@ static int bmp_active_thread(struct thread *t)
 
        sockunion2str(&ba->addrs[ba->addrpos], buf, sizeof(buf));
        if (ret < 0 || status != 0) {
-               zlog_warn("bmp[%s]: failed to connect to %s:%d",
-                         ba->hostname, buf, ba->port);
+               ba->last_err = strerror(status);
+               zlog_warn("bmp[%s]: failed to connect to %s:%d: %s",
+                         ba->hostname, buf, ba->port, ba->last_err);
                goto out_next;
        }
 
@@ -2067,9 +2079,12 @@ DEFPY(show_bmp,
        struct bmp_bgp *bmpbgp;
        struct bmp_targets *bt;
        struct bmp_listener *bl;
+       struct bmp_active *ba;
        struct bmp *bmp;
        struct ttable *tt;
        char buf[SU_ADDRSTRLEN];
+       char uptime[BGP_UPTIME_LEN];
+       char *out;
 
        frr_each(bmp_bgph, &bmp_bgph, bmpbgp) {
                vty_out(vty, "BMP state for BGP %s:\n\n",
@@ -2118,6 +2133,51 @@ DEFPY(show_bmp,
                                        sockunion2str(&bl->addr, buf,
                                                      SU_ADDRSTRLEN), bl->port);
 
+                       vty_out(vty, "\n    Outbound connections:\n");
+                       tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+                       ttable_add_row(tt, "remote|state||timer");
+                       ttable_rowseps(tt, 0, BOTTOM, true, '-');
+                       frr_each (bmp_actives, &bt->actives, ba) {
+                               const char *state_str = "?";
+
+                               if (ba->bmp) {
+                                       peer_uptime(ba->bmp->t_up.tv_sec,
+                                                   uptime, sizeof(uptime),
+                                                   false, NULL);
+                                       ttable_add_row(tt, "%s:%d|Up|%s|%s",
+                                                      ba->hostname, ba->port,
+                                                      ba->bmp->remote, uptime);
+                                       continue;
+                               }
+
+                               uptime[0] = '\0';
+
+                               if (ba->t_timer) {
+                                       long trem = thread_timer_remain_second(
+                                               ba->t_timer);
+
+                                       peer_uptime(monotime(NULL) - trem,
+                                                   uptime, sizeof(uptime),
+                                                   false, NULL);
+                                       state_str = "RetryWait";
+                               } else if (ba->t_read) {
+                                       state_str = "Connecting";
+                               } else if (ba->resq.callback) {
+                                       state_str = "Resolving";
+                               }
+
+                               ttable_add_row(tt, "%s:%d|%s|%s|%s",
+                                              ba->hostname, ba->port,
+                                              state_str,
+                                              ba->last_err ? ba->last_err : "",
+                                              uptime);
+                               continue;
+                       }
+                       out = ttable_dump(tt, "\n");
+                       vty_out(vty, "%s", out);
+                       XFREE(MTYPE_TMP, out);
+                       ttable_del(tt);
+
                        vty_out(vty, "\n    %zu connected clients:\n",
                                        bmp_session_count(&bt->sessions));
                        tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
@@ -2130,14 +2190,17 @@ DEFPY(show_bmp,
 
                                pullwr_stats(bmp->pullwr, &total, &q, &kq);
 
-                               ttable_add_row(tt, "%s|-|%Lu|%Lu|%Lu|%Lu|%zu|%zu",
-                                              bmp->remote,
+                               peer_uptime(bmp->t_up.tv_sec, uptime,
+                                           sizeof(uptime), false, NULL);
+
+                               ttable_add_row(tt, "%s|%s|%Lu|%Lu|%Lu|%Lu|%zu|%zu",
+                                              bmp->remote, uptime,
                                               bmp->cnt_update,
                                               bmp->cnt_mirror,
                                               bmp->cnt_mirror_overruns,
                                               total, q, kq);
                        }
-                       char *out = ttable_dump(tt, "\n");
+                       out = ttable_dump(tt, "\n");
                        vty_out(vty, "%s", out);
                        XFREE(MTYPE_TMP, out);
                        ttable_del(tt);