]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Add some statistics
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 3 Dec 2019 17:05:41 +0000 (18:05 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 3 Dec 2019 17:05:41 +0000 (18:05 +0100)
Add some statistic counters to BGP consistent with BGP MIB (RFC 4273),
including persistent 'FSM established transitions'.

proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c

index 2a64958a004a92a094c5ed8499fc1a2ab1c3bf1a..83105a689f7ada323080d036b77c6cb6c22cbf44 100644 (file)
@@ -545,6 +545,8 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
   struct bgp_channel *c;
 
   BGP_TRACE(D_EVENTS, "BGP session established");
+  p->last_established = current_time();
+  p->stats.fsm_established_transitions++;
 
   /* For multi-hop BGP sessions */
   if (ipa_zero(p->local_ip))
@@ -685,6 +687,7 @@ static void
 bgp_conn_leave_established_state(struct bgp_proto *p)
 {
   BGP_TRACE(D_EVENTS, "BGP session closed");
+  p->last_established = current_time();
   p->conn = NULL;
 
   if (p->p.proto_state == PS_UP)
@@ -1520,6 +1523,12 @@ bgp_start(struct proto *P)
   p->gr_ready = 0;
   p->gr_active_num = 0;
 
+  /* Reset some stats */
+  p->stats.rx_messages = p->stats.tx_messages = 0;
+  p->stats.rx_updates = p->stats.tx_updates = 0;
+  p->stats.rx_bytes = p->stats.tx_bytes = 0;
+  p->last_rx_update = 0;
+
   p->event = ev_new_init(p->p.pool, bgp_decision, p);
   p->startup_timer = tm_new_init(p->p.pool, bgp_startup_timeout, p, 0, 0);
   p->gr_timer = tm_new_init(p->p.pool, bgp_graceful_restart_timeout, p, 0, 0);
@@ -2448,6 +2457,16 @@ bgp_show_proto_info(struct proto *P)
            tm_remains(p->conn->keepalive_timer), p->conn->keepalive_time);
   }
 
+  struct bgp_stats *s = &p->stats;
+  cli_msg(-1006, "    FSM established transitions: %u",
+         s->fsm_established_transitions);
+  cli_msg(-1006, "    Rcvd messages:    %u total / %u updates / %lu bytes",
+         s->rx_messages, s->rx_updates, s->rx_bytes);
+  cli_msg(-1006, "    Sent messages:    %u total / %u updates / %lu bytes",
+         s->tx_messages, s->tx_updates, s->tx_bytes);
+  cli_msg(-1006, "    Last rcvd update elapsed time: %t s",
+         p->last_rx_update ? (current_time() - p->last_rx_update) : 0);
+
   if ((p->last_error_class != BE_NONE) &&
       (p->last_error_class != BE_MAN_DOWN))
   {
index d336132bf2c55077ece4366b36904326c0d3052b..03b92bd87306d59077670c557a46d621c04f0451 100644 (file)
@@ -245,6 +245,14 @@ struct bgp_socket {
   u32 uc;                              /* Use count */
 };
 
+struct bgp_stats {
+  uint rx_messages, tx_messages;
+  uint rx_updates, tx_updates;
+  u64  rx_bytes, tx_bytes;
+
+  uint fsm_established_transitions;
+};
+
 struct bgp_conn {
   struct bgp_proto *bgp;
   struct birdsock *sk;
@@ -303,6 +311,9 @@ struct bgp_proto {
   struct bgp_socket *sock;             /* Shared listening socket */
   struct bfd_request *bfd_req;         /* BFD request, if BFD is used */
   struct birdsock *postponed_sk;       /* Postponed incoming socket for dynamic BGP */
+  struct bgp_stats stats;              /* BGP statistics */
+  btime last_established;              /* Last time of enter/leave of established state */
+  btime last_rx_update;                        /* Last time of RX update */
   ip_addr link_addr;                   /* Link-local version of local_ip */
   event *event;                                /* Event for respawning and shutting process */
   timer *startup_timer;                        /* Timer used to delay protocol startup due to previous errors (startup_delay) */
index 0bc63c5586e54ba3351a75dc2857446869b42c4a..ed878e41597d826a5fcab46aff2ef5810031ad2f 100644 (file)
@@ -2300,6 +2300,7 @@ again: ;
 
 done:
   BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
+  p->stats.tx_updates++;
   lp_flush(s.pool);
 
   return res;
@@ -2335,6 +2336,7 @@ bgp_create_end_mark(struct bgp_channel *c, byte *buf)
   struct bgp_proto *p = (void *) c->c.proto;
 
   BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
+  p->stats.tx_updates++;
 
   return (c->afi == BGP_AF_IPV4) ?
     bgp_create_ip_end_mark(c, buf):
@@ -2415,6 +2417,8 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
   ea_list *ea = NULL;
 
   BGP_TRACE_RL(&rl_rcv_update, D_PACKETS, "Got UPDATE");
+  p->last_rx_update = current_time();
+  p->stats.rx_updates++;
 
   /* Workaround for some BGP implementations that skip initial KEEPALIVE */
   if (conn->state == BS_OPENCONFIRM)
@@ -2702,6 +2706,9 @@ bgp_send(struct bgp_conn *conn, uint type, uint len)
   sock *sk = conn->sk;
   byte *buf = sk->tbuf;
 
+  conn->bgp->stats.tx_messages++;
+  conn->bgp->stats.tx_bytes += len;
+
   memset(buf, 0xff, 16);               /* Marker */
   put_u16(buf+16, len);
   buf[18] = type;
@@ -3075,6 +3082,8 @@ bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
   byte type = pkt[18];
 
   DBG("BGP: Got packet %02x (%d bytes)\n", type, len);
+  conn->bgp->stats.rx_messages++;
+  conn->bgp->stats.rx_bytes += len;
 
   if (conn->bgp->p.mrtdump & MD_MESSAGES)
     bgp_dump_message(conn, pkt, len);