]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
SNMP: Handle unresponsive master agent
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Thu, 15 Aug 2024 09:52:38 +0000 (11:52 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Thu, 15 Aug 2024 09:53:10 +0000 (11:53 +0200)
proto/snmp/snmp.c
proto/snmp/snmp.h
proto/snmp/subagent.c

index 1f0127d1f5eaabd4d432e5e9f1687ab50d1e3594..fbc2cf0b448fb5dd55f8253ade07db4793d0c19e 100644 (file)
@@ -207,7 +207,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
     if (cf->trans_type == SNMP_TRANS_TCP)
     {
       s->type = SK_TCP_ACTIVE;
-      //s->saddr = ipa_from_ip4(p->local_ip);
       s->daddr = p->remote_ip;
       s->dport = p->remote_port;
       s->rbsize = SNMP_RX_BUFFER_SIZE;
@@ -221,7 +220,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
       s->tbsize = SNMP_TX_BUFFER_SIZE;
     }
 
-    /* s->tos = IP_PREC_INTERNET_CONTROL */
     s->tx_hook = snmp_connected;
     s->err_hook = snmp_sock_err;
 
@@ -262,6 +260,9 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
     p->sock->tx_hook = snmp_tx;
 
     snmp_register_mibs(p);
+
+    // TODO timer for CONN
+
     return PS_START;
 
   case SNMP_CONN:
index d52484eb86d39d8d9fba5b8c8d416b5e4391c03d..9a787c6eaa00430b05a0ae1c44b111216bb9334a 100644 (file)
@@ -136,6 +136,7 @@ struct snmp_proto {
 
   struct mib_tree *mib_tree;
   int verbose;
+  uint pings;
   u32 ignore_ping_id;
 };
 
index 083ae99830754cead70aaaeb14b5f97094187251..4e43245808bdc8796cd772e7c7899b74289f6a85 100644 (file)
@@ -781,13 +781,21 @@ parse_response(struct snmp_proto *p, byte *res)
 
   uint pkt_size = LOAD_U32(h->payload);
 
+  if (p->ignore_ping_id && LOAD_U32(h->packet_id) == p->ignore_ping_id)
+  {
+    p->pings--;
+    p->ignore_ping_id = 0;
+  }
+
+  /* Number of agentx-Ping-PDU without response */
+  if (p->pings > 5)
+    snmp_reset(p);
+
   switch (r->error)
   {
     case AGENTX_RES_NO_ERROR:
       if (p->verbose || LOAD_U32(h->packet_id) != p->ignore_ping_id)
        TRACE(D_PACKETS, "SNMP received agentx-Response-PDU");
-      if (LOAD_U32(h->packet_id) == p->ignore_ping_id)
-       p->ignore_ping_id = 0;
       do_response(p, res);
       break;
 
@@ -796,8 +804,6 @@ parse_response(struct snmp_proto *p, byte *res)
     case AGENTX_RES_REQUEST_DENIED:
     case AGENTX_RES_UNKNOWN_REGISTER:
       TRACE(D_PACKETS, "SNMP received agentx-Response-PDU with error %u", r->error);
-      if (LOAD_U32(h->packet_id) == p->ignore_ping_id)
-       p->ignore_ping_id = 0;
       snmp_register_ack(p, r);
       break;
 
@@ -1361,6 +1367,8 @@ snmp_ping(struct snmp_proto *p)
   /* sending only header */
   uint s = update_packet_size(h, (byte *) h + AGENTX_HEADER_SIZE);
 
+  if (p->packet_id)
+    p->pings++;
   sk_send(sk, s);
 }