]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
SNMP: Progress
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Fri, 9 Aug 2024 19:05:32 +0000 (21:05 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Fri, 9 Aug 2024 19:05:32 +0000 (21:05 +0200)
Remove old logging messages, improve and correct function documentation,
minor tweaks and bugfixes

proto/snmp/bgp4_mib.c
proto/snmp/config.Y
proto/snmp/mib_tree.c
proto/snmp/snmp.c
proto/snmp/snmp.h
proto/snmp/snmp_utils.c
proto/snmp/subagent.c
proto/snmp/subagent.h

index b13ed463dc11b3b43363b2a75034a008c72ef7ed..9a0418fd5f913fbfe6e230b7c1dcecbb32ef56fc 100644 (file)
@@ -144,7 +144,7 @@ snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_
     addr->ids[ENTRY_TYPE] = BGP4_MIB_REMOTE_ADDR;
     ip4_to_oid(addr, ip4);
   }
-  /* We have enough space inside the TX-buffer prepared */
+  /* We have enough space inside the TX buffer prepared */
   struct snmp_pdu dummy = { 0 };
   dummy.sr_vb_start = addr_vb;
   snmp_varbind_ip4(&dummy, ip4);
@@ -248,6 +248,7 @@ snmp_bgp4_register(struct snmp_proto *p)
     STORE_U8(oid->n_subid, ARRAY_SIZE(bgp_mib_prefix));
     STORE_U8(oid->prefix, SNMP_MGMT);
 
+    // TODO use STATIC_OID
     memcpy(oid->ids, bgp_mib_prefix, sizeof(bgp_mib_prefix));
     reg->oid = oid;
     reg->reg_hook_ok = snmp_bgp_reg_ok;
@@ -257,7 +258,7 @@ snmp_bgp4_register(struct snmp_proto *p)
      * We set both upper bound and index to zero, therefore only single OID
      * is being registered.
      */
-    snmp_register(p, oid, 0, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT);
+    snmp_register(p, oid, 0, 0, SNMP_REGISTER_TREE);
   }
 }
 
@@ -267,7 +268,6 @@ snmp_bgp_valid_ip4(const struct oid *o)
   return snmp_valid_ip4_index(o, 5);
 }
 
-
 static inline ip4_addr
 ip4_from_oid(const struct oid *o)
 {
@@ -332,7 +332,6 @@ print_bgp_record(const struct bgp_proto *bgp_proto)
   DBG("  incoming_conn state: %u", bgp_proto->incoming_conn.state + 1);
 }
 
-
 static inline enum snmp_search_res
 populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto, const struct bgp_conn
 **conn, const struct bgp_stats **stats, const struct bgp_config **config)
@@ -341,23 +340,16 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto
   if (snmp_bgp_valid_ip4(oid) && LOAD_U8(oid->n_subid) == 9)
     *addr = ip4_from_oid(oid);
   else
-  {
-    snmp_log("populate() invalid ip4");
     return SNMP_SEARCH_NO_INSTANCE;
-  }
 
   struct snmp_bgp_peer *pe = snmp_hash_find(c->p, *addr);
   if (!pe)
-  {
-    snmp_log("populate() hash find failed");
     return SNMP_SEARCH_NO_INSTANCE;
-  }
 
   const struct bgp_proto *bgp_proto;
   *proto = bgp_proto = pe->bgp_proto;
   if (!ipa_is_ip4(bgp_proto->remote_ip))
   {
-    log(L_ERR "%s: Found BGP protocol instance with IPv6 address", bgp_proto->p.name);
     c->error = AGENTX_RES_GEN_ERROR;
     return SNMP_SEARCH_NO_INSTANCE;
   }
@@ -366,8 +358,6 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto
   if (!ip4_equal(proto_ip, pe->peer_ip))
   {
     /* Here, we could be in problem as the bgp_proto IP address could be changed */
-    log(L_ERR "%s: Stored hash key IP address and peer remote address differ "
-      "(%I, %I).", bgp_proto->p.name, proto_ip, pe->peer_ip);
     c->error = AGENTX_RES_GEN_ERROR;
     return SNMP_SEARCH_NO_INSTANCE;
   }
@@ -376,11 +366,9 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto
   *stats = &bgp_proto->stats;
   *config = bgp_proto->cf;
 
-  snmp_log("populate() ok");
   return SNMP_SEARCH_OK;
 }
 
-
 /*
  *
  *    MIB tree fill hooks
@@ -390,7 +378,6 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto
 static enum snmp_search_res
 fill_bgp_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill ver");
   if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3)
     return SNMP_SEARCH_NO_INSTANCE;
   c->size -= snmp_str_size_from_len(1);
@@ -401,7 +388,6 @@ fill_bgp_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_local_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill as");
   if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3)
     return SNMP_SEARCH_NO_INSTANCE;
   snmp_varbind_int(c, c->p->bgp_local_as);
@@ -411,7 +397,6 @@ fill_local_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_peer_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill peer id");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -431,7 +416,6 @@ fill_peer_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_peer_state(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill peer state");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -447,7 +431,6 @@ fill_peer_state(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_admin_status(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill adm status");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -464,7 +447,6 @@ fill_admin_status(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_neg_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill neg ver");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -483,13 +465,10 @@ fill_neg_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_local_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("bgp4_mib fill local addr");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
 
-  snmp_log("fill local addr result %u", res);
-
   if (res != SNMP_SEARCH_OK)
     return res;
 
@@ -500,7 +479,6 @@ fill_local_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_local_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("bgp4_mib fill local port");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -514,7 +492,6 @@ fill_local_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_remote_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("bgp4_mib fill remote addr");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -528,7 +505,6 @@ fill_remote_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_remote_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("bgp4_mib fill remote port");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -542,7 +518,6 @@ fill_remote_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_remote_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill rem as");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -556,7 +531,6 @@ fill_remote_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_in_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill in updates");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -570,7 +544,6 @@ fill_in_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_out_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill out updates");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -584,7 +557,6 @@ fill_out_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_in_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill in total");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -598,7 +570,6 @@ fill_in_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_out_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill out total");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -612,7 +583,6 @@ fill_out_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_last_err(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill last err");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -629,7 +599,6 @@ fill_last_err(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_established_trans(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill est trans");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -644,14 +613,12 @@ fill_established_trans(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_established_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill est time");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   if (res != SNMP_SEARCH_OK)
     return res;
 
-
   snmp_varbind_gauge32(c,
        (current_time() - bgp_proto->last_established) TO_S);
   return SNMP_SEARCH_OK;
@@ -660,7 +627,6 @@ fill_established_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_retry_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill retry int");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -674,7 +640,6 @@ fill_retry_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_hold_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill hold time");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -688,7 +653,6 @@ fill_hold_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_keep_alive(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill keepalive");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -706,7 +670,6 @@ fill_keep_alive(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_hold_time_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill hold time c");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -720,14 +683,12 @@ fill_hold_time_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_keep_alive_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill keepalive c");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   if (res != SNMP_SEARCH_OK)
     return res;
 
-
   if (!bgp_conf->keepalive_time)
     snmp_varbind_int(c, 0);
   else
@@ -739,7 +700,6 @@ fill_keep_alive_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_min_as_org_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill min org int");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -754,7 +714,6 @@ fill_min_as_org_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_route_adv_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill rt adv int");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -769,7 +728,6 @@ fill_route_adv_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_in_update_elapsed_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fil in elapsed");
   enum snmp_search_res res;
   DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
   res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
@@ -785,7 +743,6 @@ fill_in_update_elapsed_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu
 static enum snmp_search_res
 fill_local_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  snmp_log("fill local id");
   if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3)
     return SNMP_SEARCH_NO_INSTANCE;
   snmp_varbind_ip4(c, c->p->bgp_local_id);
@@ -797,7 +754,7 @@ fill_local_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
  * @state: MIB tree walk state
  * @c: SNMP PDU context data
  *
- * Update TX-buffer VarBind name to next peer address.
+ * Update TX buffer VarBind name to next peer address.
  */
 static int
 bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c)
@@ -831,7 +788,6 @@ bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c)
     STORE_U8(oid->include, 1);
   }
 
-
   ASSUME(oid->n_subid == 9);
   /* Stack has one more node for empty prefix (tree root) */
   ASSUME(state->stack_pos > 10);
@@ -903,10 +859,6 @@ snmp_bgp4_start(struct snmp_proto *p)
 {
   agentx_available_mibs[BGP4_MIB_ID] = (struct oid *) &bgp4_mib_oid;
 
-  snmp_log("snmp_bgp4_start setting bgp4_mib oid %u %p %p %p",
-    BGP4_MIB_ID, &agentx_available_mibs[BGP4_MIB_ID], agentx_available_mibs[BGP4_MIB_ID], &bgp4_mib_oid);
-
-
   struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
 
   /* Create binding to BGP protocols */
index 3610bdce8fd68d62e2401302c7fab26a928147a4..a9b25d2eaf91347c911e3ee371cf110507781a32 100644 (file)
@@ -49,9 +49,6 @@ snmp_proto_item:
     if (SNMP_CFG->trans_type != SNMP_TRANS_DEFAULT)
       cf_error("Duplicit option remote address");
 
-    // TODO
-    //if (ip4_zero($3)) cf_error("Invalid remote ip address");
-
     SNMP_CFG->remote_ip = $3;
     SNMP_CFG->trans_type = SNMP_TRANS_TCP;
   }
@@ -78,9 +75,11 @@ snmp_proto_item:
   }
  | MESSAGE TIMEOUT expr_us {
     /* TODO */
-    if ($3 TO_S > 255) log(L_WARN, "%s: msg", this_proto->name);
-    if ($3 TO_S < 1) log(L_WARN, "%s: msg", this_proto->name);
-    if (($3 TO_S) - (int)($3 TO_S) > 0) log(L_WARN, "%s: ", this_proto->name);
+    if ($3 TO_S > 255 || $3 TO_S < 1)
+      log(L_WARN "resolution of AgentX message timeout is from 1 to 255 s.");
+    if (($3 TO_S) - (int)($3 TO_S) > 0)
+      log(L_WARN "AgentX message timeout cannot use second fraction, "
+       "will use rounded up value.");
     SNMP_CFG->timeout = $3;
   }
 /*
index d5dae36337a496704bad2618e4de0862d87e6461..af0b7c094478f13a5800ca9b36d7b05143154554 100644 (file)
@@ -794,10 +794,7 @@ mib_tree_walk_next_leaf(const struct mib_tree *t, struct mib_walk_state *walk, u
   (void)t;
 
   if (walk->stack_pos == 0)
-  {
-    snmp_log("walk next leaf no leafs");
     return NULL;
-  }
 
   u32 next_id = skip;
   mib_node_u *node = walk->stack[walk->stack_pos - 1];
@@ -812,7 +809,6 @@ mib_tree_walk_next_leaf(const struct mib_tree *t, struct mib_walk_state *walk, u
   {
     /* walk->stack_pos == 1, so we NULL out the last stack field */
     walk->stack[--walk->stack_pos] = NULL;
-    snmp_log("walk next leaf single leaf");
     return NULL;
   }
 
@@ -822,10 +818,7 @@ continue_while:
     node = walk->stack[walk->stack_pos - 1];
 
     if (mib_node_is_leaf(node))
-    {
-      snmp_log("walk next leaf %p at level %u", node, walk->stack_pos - 1);
       return (struct mib_leaf *) node;
-    }
 
     struct mib_node *node_inner = &node->inner;
     for (u32 id = next_id; id < node_inner->child_len; id++)
@@ -845,7 +838,6 @@ continue_while:
     walk->stack[--walk->stack_pos] = NULL;
   }
 
-  snmp_log("walk next leaf no more leafs");
   return NULL;
 }
 
index 889e486dd289fd4f1e8709efd3e8ed5903c6f6b4..2200cca288e369cc51b5891de12d812e406bf948 100644 (file)
@@ -49,7 +49,7 @@
  *    | SNMP_INIT      |     entry state after call snmp_start()
  *    +-----------------+
  *       |
- *       |   acquiring object lock for communication socket
+ *       |   acquiring object lock for tcp communication socket
  *       V
  *    +-----------------+
  *    | SNMP_LOCKED    |     object lock aquired
  *    | SNMP_OPEN      |     socket created, starting subagent
  *    +-----------------+
  *       |
- *       |   BIRD receive response for Open-PDU
+ *       |   BIRD receive response for agentx-Open-PDU
  *       V
  *    +-----------------+
  *    | SNMP_REGISTER   |     session was established, subagent registers MIBs
  *    +-----------------+
  *       |
- *       |   subagent received responses for all registration requests
+ *       |   subagent received response for any registration requests
  *       V
  *    +-----------------+
  *    | SNMP_CONN      |     everything is set
  *    +-----------------+
  *       |
- *       |   function snmp_shutdown() is called, BIRD sends Close-PDU
+ *       |   received malformed PDU, protocol disabled,
+ *       |   BIRD sends agentx-Close-PDU or agentx-Response-PDU with an error
  *       V
  *    +-----------------+
- *    | SNMP_STOP      |     waiting for response
+ *    | SNMP_STOP      |     waiting until the prepared PDUs are sent
  *    +-----------------+
  *       |
- *       |   cleaning old state information
+ *       |   cleaning protocol state
  *       V
  *    +-----------------+
  *    | SNMP_DOWN      |     session is closed
  *    +-----------------+
  *
  *
- *    +-----------------+
- *    | SNMP_RESET      |     waiting to transmit response to malformed packet
- *    +-----------------+
- *      |
- *       |    response was send, reseting the session (with socket)
- *       |
- *      \--> SNMP_LOCKED
- *
  *
  *  Erroneous transitions:
- *    SNMP is UP in states SNMP_CONN and also in SNMP_REGISTER because the
- *    session is establised and the GetNext request should be responsed
- *    without regard to MIB registration.
- *
- *    When the session has been closed for some reason (socket error, receipt of
- *    Close-PDU) SNMP cleans the session information and message queue and goes
- *    back to the SNMP_LOCKED state.
+ *    SNMP is UP (PS_UP) in states SNMP_CONN and also in SNMP_REGISTER because
+ *    the session is establised and the GetNext request should be responsed
+ *    without regards to MIB registration.
  *
  *    Reconfiguration is done in similar fashion to BGP, the reconfiguration
  *    request is declined, the protocols is stoped and started with new
 #include "mib_tree.h"
 #include "bgp4_mib.h"
 
-// TODO: remove me
-#include "proto/bgp/bgp.h"
-
 const char agentx_master_addr[] = AGENTX_MASTER_ADDR;
 const struct oid *agentx_available_mibs[AGENTX_MIB_COUNT + 1] = { 0 };
 
@@ -133,6 +119,16 @@ static void snmp_sock_err(sock *sk, int err);
 static void snmp_stop_timeout(timer *tm);
 static void snmp_cleanup(struct snmp_proto *p);
 
+static const char *snmp_state_str[] = {
+  [SNMP_INIT]    = "acquiring address lock",
+  [SNMP_LOCKED]          = "address lock acquired",
+  [SNMP_OPEN]    = "starting AgentX subagent",
+  [SNMP_REGISTER] = "registering MIBs",
+  [SNMP_CONN]    = "AgentX session established",
+  [SNMP_STOP]    = "stopping AgentX subagent",
+  [SNMP_DOWN]    = "protocol down",
+};
+
 /*
  * agentx_get_mib_init - init function for agentx_get_mib()
  * @p: SNMP instance protocol pool
@@ -154,6 +150,7 @@ void agentx_get_mib_init(pool *p)
 
 /*
  * agentx_get_mib - classify an OID based on MIB prefix
+ * @o: Object Identifier to classify
  */
 enum agentx_mibs agentx_get_mib(const struct oid *o)
 {
@@ -185,29 +182,28 @@ snmp_rx_skip(sock UNUSED *sk, uint UNUSED size)
 }
 
 /*
- * snmp_tx_skip - handle empty TX-buffer during session reset
+ * snmp_tx_skip - handle empty TX buffer during session reset
  * @sk: communication socket
  *
- * The socket tx_hook is called when the TX-buffer is empty, i.e. all data was
+ * The socket tx_hook is called when the TX buffer is empty, i.e. all data was
  * send. This function is used only when we found malformed PDU and we are
- * resetting the established session. If called, we are reseting the session.
+ * resetting the established session. If called, we perform a SNMP protocol
+ * state change.
  */
 static void
 snmp_tx_skip(sock *sk)
 {
   struct snmp_proto *p = sk->data;
-  proto_notify_state(&p->p, snmp_set_state(p, SNMP_DOWN));
+  proto_notify_state(&p->p, snmp_set_state(p, SNMP_STOP));
 }
 
 /*
  * snmp_set_state - change state with associated actions
- * @p - SNMP protocol instance
- * @state - new SNMP protocol state
- *
- * This function does not notify the bird about protocol state. It is therefore
- * a responsibility of the caller to use the returned value appropriately.
+ * @p: SNMP protocol instance
+ * @state: new SNMP protocol state
  *
- * Return current protocol state.
+ * This function does not notify the bird about protocol state. Return current
+ * protocol state (PS_UP, ...).
  */
 int
 snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
@@ -215,14 +211,12 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
   enum snmp_proto_state last = p->state;
   const struct snmp_config *cf = (struct snmp_config *) p->p.cf;
 
-  TRACE(D_EVENTS, "SNMP changing state to %u", state);
-
   p->state = state;
 
   switch (state)
   {
   case SNMP_INIT:
-    DBG("snmp -> SNMP_INIT\n");
+    TRACE(D_EVENTS, "TODO");
     ASSERT(last == SNMP_DOWN);
 
     if (cf->trans_type == SNMP_TRANS_TCP)
@@ -230,11 +224,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
       /* We need to lock the IP address */
       struct object_lock *lock;
       lock = p->lock = olock_new(p->pool);
-
-      /*
-       * lock->iface
-       * lock->vrf
-       */
       lock->addr = p->remote_ip;
       lock->port = p->remote_port;
       lock->type = OBJLOCK_TCP;
@@ -244,18 +233,19 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
       return PS_START;
     }
 
+    last = SNMP_INIT;
     p->state = state = SNMP_LOCKED;
     /* Fall thru */
 
   case SNMP_LOCKED:
-    DBG("snmp -> SNMP_LOCKED\n");
-    ASSERT(last == SNMP_INIT || SNMP_RESET);
+    TRACE(D_EVENTS, "snmp %s: address lock acquired", p->p.name);
+    ASSERT(last == SNMP_INIT);
     sock *s = sk_new(p->pool);
 
     if (cf->trans_type == SNMP_TRANS_TCP)
     {
       s->type = SK_TCP_ACTIVE;
-      s->saddr = ipa_from_ip4(p->local_ip);
+      //s->saddr = ipa_from_ip4(p->local_ip);
       s->daddr = p->remote_ip;
       s->dport = p->remote_port;
       s->rbsize = SNMP_RX_BUFFER_SIZE;
@@ -279,65 +269,69 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
     /* Try opening the socket, schedule a retry on fail */
     if (sk_open(s) < 0)
     {
+      TRACE(D_EVENTS, "opening of communication socket failed");
       rfree(s);
       p->sock = NULL;
+      // TODO handle 0 timeout
       tm_start(p->startup_timer, p->timeout);
     }
     return PS_START;
 
   case SNMP_OPEN:
-    DBG("snmp -> SNMP_OPEN\n");
+    TRACE(D_EVENTS, "communication socket opened, starting AgentX subagent");
     ASSERT(last == SNMP_LOCKED);
+
     p->sock->rx_hook = snmp_rx;
     p->sock->tx_hook = NULL;
+
     snmp_start_subagent(p);
+
     p->startup_timer->hook = snmp_stop_timeout;
     tm_start(p->startup_timer, 1 S);
+
     return PS_START;
 
   case SNMP_REGISTER:
-    DBG("snmp -> SNMP_REGISTER\n");
+    TRACE(D_EVENTS, "registering MIBs");
     ASSERT(last == SNMP_OPEN);
+
     tm_stop(p->startup_timer); /* stop timeout */
+
+    p->sock->rx_hook = snmp_rx;
+    p->sock->tx_hook = snmp_tx;
+
     snmp_register_mibs(p);
     return PS_START;
 
   case SNMP_CONN:
-    DBG("snmp -> SNMP_CONN\n");
+    TRACE(D_EVENTS, "MIBs registered");
     ASSERT(last == SNMP_REGISTER);
     return PS_UP;
 
   case SNMP_STOP:
-    DBG("snmp -> SNMP_STOP\n");
-    ASSUME(last == SNMP_REGISTER || last == SNMP_CONN);
-    snmp_stop_subagent(p);
-    // FIXME: special treatment for SNMP_OPEN last state?
-    p->sock->rx_hook = snmp_rx_skip;
-    p->sock->tx_hook = snmp_tx_skip;
+    if (p->sock && p->state != SNMP_OPEN)
+    {
+      TRACE(D_EVENTS, "closing AgentX session");
+      if (p->state == SNMP_OPEN || p->state == SNMP_REGISTER ||
+         p->state == SNMP_CONN)
+       snmp_stop_subagent(p);
 
-    p->startup_timer->hook = snmp_stop_timeout;
-    tm_start(p->startup_timer, p->timeout);
-    return PS_STOP;
+      p->sock->rx_hook = snmp_rx_skip;
+      p->sock->tx_hook = snmp_tx_skip;
+
+      p->startup_timer->hook = snmp_stop_timeout;
+      tm_start(p->startup_timer, 150 MS);
+      return PS_STOP;
+    }
+
+    p->state = state = SNMP_DOWN;
+    /* Fall thru */
 
   case SNMP_DOWN:
-    DBG("snmp -> SNMP_DOWN\n");
-    ASSERT(last == SNMP_STOP || last == SNMP_RESET);
+    TRACE(D_EVENTS, "AgentX session closed");
     snmp_cleanup(p);
-    // FIXME: handle the state in which we call proto_notify_state and
-    // immediately return PS_DOWN from snmp_shutdown()
     return PS_DOWN;
 
-  case SNMP_RESET:
-    // TODO remove SNMP_RESET state
-    DBG("snmp -> SNMP_RESET\n");
-    ASSUME(last == SNMP_REGISTER || last == SNMP_CONN);
-    ASSUME(p->sock);
-    snmp_stop_subagent(p);
-    // FIXME: special treatment for SNMP_OPEN last state?
-    p->sock->rx_hook = snmp_rx_skip;
-    p->sock->tx_hook = snmp_tx_skip;
-    return PS_STOP;
-
   default:
     die("unknown snmp state transition");
     return PS_DOWN;
@@ -346,7 +340,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state)
 
 /*
  * snmp_init - preinitialize SNMP instance
- * @CF - SNMP configuration generic handle
+ * @CF: SNMP configuration generic handle
  *
  * Returns a generic handle pointing to preinitialized SNMP procotol
  * instance.
@@ -358,7 +352,6 @@ snmp_init(struct proto_config *CF)
   struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
 
   p->rl_gen = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
-
   p->state = SNMP_DOWN;
 
   return P;
@@ -366,12 +359,10 @@ snmp_init(struct proto_config *CF)
 
 /*
  * snmp_cleanup - free all resources allocated by SNMP protocol
- * @p - SNMP protocol instance
+ * @p: SNMP protocol instance
  *
  * This function forcefully stops and cleans all resources and memory acqiured
  * by given SNMP protocol instance, such as timers, lists, hash tables etc.
- * Function snmp_cleanup() does not change the protocol state to PS_DOWN for
- * practical reasons, it should be done by the caller.
  */
 static inline void
 snmp_cleanup(struct snmp_proto *p)
@@ -407,7 +398,7 @@ snmp_cleanup(struct snmp_proto *p)
 
 /*
  * snmp_connected - start AgentX session on created socket
- * @sk - socket owned by SNMP protocol instance
+ * @sk: socket owned by SNMP protocol instance
  *
  * Starts the AgentX communication by sending an agentx-Open-PDU.
  * This function is internal and shouldn't be used outside the SNMP module.
@@ -426,47 +417,35 @@ snmp_connected(sock *sk)
  * We wait until the last PDU written into the socket is send while ignoring all
  * incomming PDUs. Then we hard reset the connection by socket closure. The
  * protocol instance is automatically restarted by nest.
- */
-void
-snmp_reset(struct snmp_proto *p)
-{
-  proto_notify_state(&p->p, snmp_set_state(p, SNMP_RESET));
-}
-
-
-/*
- * snmp_stop - close AgentX session
- * @p: SNMP protocol instance
  *
- * We write agentx-Close-PDU into the socket, wait until all written PDUs are
- * send and then close the socket. The protocol instance is automatically
- * restarted by nest.
+ * Return protocol state (PS_STOP, ...).
  */
-void
-snmp_stop(struct snmp_proto *p)
+int
+snmp_reset(struct snmp_proto *p)
 {
-  // TODO: add option for passing close reason for agentx-Close-PDU
-  proto_notify_state(&p->p, snmp_set_state(p, SNMP_STOP));
+  int proto_state = snmp_set_state(p, SNMP_STOP);
+  proto_notify_state(&p->p, proto_state);
+  return proto_state;
 }
 
 
 /*
  * snmp_sock_err - handle errors on socket by reopenning the socket
- * @sk - socket owned by SNMP protocol instance
- * @err - socket error errno
+ * @sk: socket owned by SNMP protocol instance
+ * @err: socket error code
  */
 static void
 snmp_sock_err(sock *sk, int UNUSED err)
 {
   struct snmp_proto *p = sk->data;
-
-  TRACE(D_EVENTS, "SNMP socket error %d", err);
-  snmp_reset(p);
+  if (err != 0)
+    TRACE(D_EVENTS, "SNMP socket error (%d)", err);
+  snmp_set_state(p, SNMP_DOWN);
 }
 
 /*
  * snmp_start_locked - open the socket on locked address
- * @lock - object lock guarding the communication mean (address, ...)
+ * @lock: object lock guarding the communication mean (address, ...)
  *
  * This function is called when the object lock is acquired. Main goal is to set
  * socket parameters and try to open configured socket. Function
@@ -487,29 +466,14 @@ snmp_start_locked(struct object_lock *lock)
     snmp_set_state(p, SNMP_LOCKED);
 }
 
-/*
- * snmp_reconnect - helper restarting the AgentX session on packet errors
- * @tm - the startup_timer holding the SNMP protocol instance
- *
- * Try to recover from an error by reseting the SNMP protocol. It is a simple
- * snmp_reset() wrapper for timers.
- */
-void
-snmp_reconnect(timer *tm)
-{
-  struct snmp_proto *p = tm->data;
-  snmp_reset(p);
-  return;
-}
-
 /*
  * snmp_startup_timeout - start the initiliazed SNMP protocol
- * @tm - the startup_timer holding the SNMP protocol instance.
+ * @tm: the startup_timer holding the SNMP protocol instance.
  *
  * When the timer rings, the function snmp_startup() is invoked.
  * This function is internal and shouldn't be used outside the SNMP module.
- * Used when we delaying the start procedure, or we want to resend
- * an agentx-Open-PDU for non-responding master agent.
+ * Used when we delaying the start procedure, or we want to retry opening
+ * the communication socket.
  */
 void
 snmp_startup_timeout(timer *tm)
@@ -519,13 +483,13 @@ snmp_startup_timeout(timer *tm)
 }
 
 /*
- * snmp_stop_timeout - a timeout for nonresponding master agent
- * @tm - the startup_timer holding the SNMP protocol instance.
+ * snmp_stop_timeout - a timeout for non-responding master agent
+ * @tm: the startup_timer holding the SNMP protocol instance.
  *
- * We are shutting down the SNMP protocol instance and we sent the
- * agentx-Close-PDU. This function forcefully closes the AgentX session and
- * stops the SNMP protocol instance. Used only when we did not receive any
- * agentx-Response-PDU for the sent closed packet (before timeout).
+ * We are trying to empty the TX buffer of communication socket. But if it is
+ * not done in reasonable amount of time, the function is called by timeout
+ * timer. We down the whole SNMP protocol with cleanup of associated data
+ * structures.
  */
 static void
 snmp_stop_timeout(timer *tm)
@@ -536,7 +500,7 @@ snmp_stop_timeout(timer *tm)
 
 /*
  * snmp_ping_timeout - send a agentx-Ping-PDU
- * @tm - the ping_timer holding the SNMP protocol instance.
+ * @tm: the ping_timer holding the SNMP protocol instance.
  *
  * Send an agentx-Ping-PDU. This function is periodically called by ping
  * timer.
@@ -550,11 +514,11 @@ snmp_ping_timeout(timer *tm)
 
 /*
  * snmp_start - Initialize the SNMP protocol instance
- * @P - SNMP protocol generic handle
+ * @P: SNMP protocol generic handle
  *
  * The first step in AgentX subagent startup is protocol initialition.
- * We must prepare lists, find BGP peers and finally asynchronously open
- * a AgentX subagent session through snmp_startup() function call.
+ * We must prepare lists, find BGP peers and finally asynchronously start
+ * a AgentX subagent session.
  */
 static int
 snmp_start(struct proto *P)
@@ -605,7 +569,7 @@ snmp_reconfigure_logic(struct snmp_proto *p, const struct snmp_config *new)
   {
     WALK_LIST(b2, old->bgp_entries)
     {
-      if (!strcmp(b1->config->name, b2->config->name))
+      if (!bstrcmp(b1->config->name, b2->config->name))
        goto skip;
     }
 
@@ -617,10 +581,29 @@ skip:
   if (bonds != 0)
     return 0;
 
+  if (old->trans_type != new->trans_type
+      || ip4_compare(old->local_ip, new->local_ip)
+      || old->local_port != new->local_port
+      || ipa_compare(old->remote_ip, new->remote_ip)
+      || !bstrcmp(old->remote_path, new->remote_path)
+      || old->remote_port != new->remote_port
+         // TODO can be changed on the fly
+      || !ip4_compare(old->bgp_local_id, new->bgp_local_id)
+      || old->bgp_local_as != new->bgp_local_as // TODO can be changed on the fly
+      || old->timeout != new->timeout
+    //|| old->startup_delay != new->startup_delay
+      || old->priority != new->priority
+      || !strncmp(old->description, new->description, UINT32_MAX))
+    return 0;
+
+  return 1;
+
+/*
   return !memcmp(((byte *) old) + sizeof(struct proto_config),
       ((byte *) new) + sizeof(struct proto_config),
       OFFSETOF(struct snmp_config, description) - sizeof(struct proto_config))
     && ! strncmp(old->description, new->description, UINT32_MAX);
+*/
 }
 
 /*
@@ -638,6 +621,8 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
   struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
   const struct snmp_config *new = SKIP_BACK(struct snmp_config, cf, CF);
 
+  // TODO do not reject reconfiguration when only BGP peer list changed
+
   /* We are searching for configuration changes */
   int config_changed = snmp_reconfigure_logic(p, new);
 
@@ -660,7 +645,7 @@ snmp_show_proto_info(struct proto *P)
 {
   struct snmp_proto *p = (void *) P;
 
-  cli_msg(-1006, "  SNMP state %u", p->state);
+  cli_msg(-1006, "  SNMP state: %s", snmp_state_str[p->state]);
   cli_msg(-1006, "  MIBs");
 
   snmp_bgp4_show_info(p);
@@ -682,19 +667,16 @@ snmp_postconfig(struct proto_config *CF)
 
 /*
  * snmp_shutdown - Forcefully stop the SNMP protocol instance
- * @P - SNMP protocol generic handle
+ * @P: SNMP protocol generic handle
  *
- * If we have established connection, we firstly stop the subagent and then
- * later cleanup the protocol. The subagent stopping consist of sending the
- * agentx-Close-PDU and changing the current protocol state to PS_STOP.
- * If we have no connection created, we simple do the cleanup.
- * The cleanup is transition straight to PS_DOWN state with snmp_cleanup() call.
+ * Simple cast-like wrapper around snmp_reset(), see more info there.
  */
 static int
 snmp_shutdown(struct proto *P)
 {
   struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
   return snmp_set_state(p, SNMP_DOWN);
+  return snmp_reset(p);
 }
 
 
index 23b74d3bc3a7a7280062965699d6fa8bae1a5dc8..b8c057d23241eeb8f8c7833259fccc7266a15100 100644 (file)
 #ifndef _BIRD_SNMP_H_
 #define _BIRD_SNMP_H_
 
+#include "nest/bird.h"
+#include "nest/protocol.h"
+#include "lib/resource.h"
 #include "lib/ip.h"
 #include "lib/socket.h"
-#include "lib/resource.h"
 #include "lib/timer.h"
-#include "nest/bird.h"
-#include "nest/protocol.h"
 #include "filter/data.h"
 
 #define SNMP_UNDEFINED 0
@@ -39,7 +39,6 @@ enum snmp_proto_state {
   SNMP_REGISTER,
   SNMP_CONN,
   SNMP_STOP,
-  SNMP_RESET,
 };
 
 struct snmp_bond {
@@ -69,7 +68,6 @@ struct snmp_config {
   btime timeout;
   btime startup_delay;
   u8 priority;
-  //struct iface *iface;  TODO
   u32 bonds;
   const char *description;       /* The order of fields is not arbitrary */
   list bgp_entries;              /* We want dynamically allocated fields to be
@@ -170,9 +168,16 @@ void snmp_startup_timeout(timer *tm);
 void snmp_reconnect(timer *tm);
 int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state);
 
-void snmp_reset(struct snmp_proto *p);
-void snmp_stop(struct snmp_proto *p);
+int snmp_reset(struct snmp_proto *p);
 
 extern const char agentx_master_addr[sizeof(AGENTX_MASTER_ADDR)];
 
+static inline int
+proto_is_snmp(const struct proto *P)
+{
+  extern struct protocol proto_snmp;
+  return P->proto == &proto_snmp;
+}
+
+
 #endif
index bd4263fa5f9d81fede27c84f70b86f55e7c19ced..bb4bb811e2d88fa2bf6fbf59a9c879a48d60cbe5 100644 (file)
@@ -66,10 +66,7 @@ snmp_varbind_set_name_len(struct snmp_pdu *c, struct agentx_varbind **vb, u8 len
   uint diff_size = (len - LOAD_U8(oid->n_subid)) * sizeof(u32);
 
   if (snmp_tbuf_reserve(c, diff_size))
-  {
-    snmp_log("varbind_set_name_len small buffer");
     oid = &(*vb)->name;
-  }
 
   ASSERT(c->size >= diff_size);
   c->size -= diff_size;
@@ -82,8 +79,7 @@ snmp_varbind_duplicate_hdr(struct snmp_pdu *c, struct agentx_varbind **vb)
 {
   ASSUME(vb != NULL && *vb != NULL);
   uint hdr_size = snmp_varbind_header_size(*vb);
-  if (snmp_tbuf_reserve(c, hdr_size))
-    snmp_log("varbind_duplicate small buffer");
+  (void) snmp_tbuf_reserve(c, hdr_size);
 
   ASSERT(c->size >= hdr_size);
   byte *buffer = c->buffer;
@@ -175,6 +171,23 @@ snmp_oid_copy2(struct oid *dest, const struct oid *src)
   memcpy(dest->ids, src->ids, LOAD_U8(src->n_subid) * sizeof(u32));
 }
 
+/*
+ * snmp_oid_from_buf - copy OID from RX buffer to dest in native byte order
+ * @dst: destination to use
+ * @src: OID to be copied from
+ */
+void
+snmp_oid_from_buf(struct oid *dst, const struct oid *src)
+{
+  dst->n_subid = LOAD_U8(src->n_subid);
+  dst->prefix = LOAD_U8(src->prefix);
+  dst->include = LOAD_U8(src->include) ? 1 : 0;
+  dst->reserved = 0;
+
+  for (uint i = 0; i < dst->n_subid; i++)
+    dst->ids[i] = LOAD_U32(src->ids[i]);
+}
+
 /*
  * snmp_oid_duplicate - duplicate an OID from memory pool
  * @pool: pool to use
@@ -256,7 +269,7 @@ snmp_varbind_hdr_size_from_oid(const struct oid *oid)
 
 /*
  * snmp_set_varbind_type - set VarBind's type field
- * @vb: Varbind inside TX-buffer
+ * @vb: Varbind inside TX buffer
  * @t: a valid type to be set
  *
  * This function assumes valid @t.
@@ -304,10 +317,10 @@ snmp_load_varbind_type(const struct agentx_varbind *vb)
 
 /*
  * snmp_get_varbind_type - loads a VarBind type
- * @vb: VarBind pointer to TX-buffer
+ * @vb: VarBind pointer to TX buffer
  *
  * This function assumes VarBind with valid type, always call snmp_test_varbind
- * for in TX-buffer VarBinds!
+ * for in TX buffer VarBinds.
  */
 inline enum agentx_type
 snmp_get_varbind_type(const struct agentx_varbind *vb)
@@ -742,7 +755,6 @@ snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib)
   r->packet_id = p->packet_id + 1;
   r->mib = mib;
 
-  snmp_log("using registration packet_id %u", r->packet_id);
   add_tail(&p->registration_queue, &r->n);
 
   return r;
@@ -751,7 +763,6 @@ snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib)
 int
 snmp_registration_match(struct snmp_registration *r, struct agentx_header *h, enum agentx_mibs mib)
 {
-  snmp_log("snmp_reg_same() r->packet_id %u p->packet_id %u", r->packet_id, h->packet_id);
   return
     (r->mib == mib) &&
     (r->session_id == h->session_id) &&
@@ -864,7 +875,7 @@ snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len)
  * @len: length of the string @str
  *
  * Beware: this function assumes there is enough space in the underlaying
- * TX-buffer. The caller has to provide that, see snmp_str_size_from_len() for
+ * TX buffer. The caller has to provide that, see snmp_str_size_from_len() for
  * more info.
  */
 void
@@ -951,7 +962,7 @@ snmp_oid_log(const struct oid *oid)
   for (int id = 0; id < oid->n_subid; id++)
     pos += snprintf(pos, buf + 1024 - pos, ".%u", oid->ids[id]);
 
-  snmp_log("%s", buf);
+  log(L_WARN, "%s", buf);
 }
 
 
@@ -1096,10 +1107,7 @@ snmp_walk_next(struct mib_tree *tree, struct mib_walk_state *walk, struct snmp_p
       int old = snmp_oid_size(&c->sr_vb_start->name);
       if (mib_tree_walk_to_oid(walk,
          &c->sr_vb_start->name, 20 * sizeof(u32)))
-      {
-       snmp_log("walk_next copy failed");
        return NULL;
-      }
 
       int new = snmp_oid_size(&c->sr_vb_start->name);
       c->buffer += (new - old);
@@ -1122,10 +1130,7 @@ snmp_walk_next(struct mib_tree *tree, struct mib_walk_state *walk, struct snmp_p
     int old = snmp_oid_size(&c->sr_vb_start->name);
     // TODO autogrow
     if (mib_tree_walk_to_oid(walk, &c->sr_vb_start->name, 20 * sizeof(u32)))
-    {
-      snmp_log("walk_next copy failed");
       return NULL;
-    }
 
     int new = snmp_oid_size(&c->sr_vb_start->name);
     c->buffer += (new - old);
@@ -1172,10 +1177,7 @@ snmp_walk_fill(struct mib_leaf *leaf, struct mib_walk_state *walk, struct snmp_p
       size = leaf->size;
   }
 
-  snmp_log("walk_fill got size %u based on lt %u ls %u, calling filler()", size, leaf->type, leaf->size);
-
-  if (snmp_tbuf_reserve(c, size))
-    snmp_log("walk_fill small buffer size");
+  (void) snmp_tbuf_reserve(c, size);
 
   enum snmp_search_res res = leaf->filler(walk, c);
 
index 470c283a346cfe0cd0b059bda0a1142d133005b1..af768a9d68a6d09c55edf33ae143980795f1f321 100644 (file)
 #include "bgp4_mib.h"
 
 /*
- * Goals:
- *  In current situation, we do not handle the dynamic BGP case.
- */
-
-/**
- *
  * Handling of malformed packet:
  *
  * When we find an error in PDU data, we create and send a response with error
  * defined by the RFC. We await until the packet is send and then we close the
- * communication socket. This implicitly closes the established session. We
- * chose this approach because we cannot easily mark the boundary between packets.
- * When we are reseting the connection, we change the snmp_state to SNMP_RESET.
- * In SNMP_RESET state we skip all received bytes and wait for snmp_tx_skip()
- * to be called. The socket's tx_hook is called when the TX-buffer is empty,
- * meaning our response (agentx-Response-PDU) was send.
+ * communication socket ignoring any possible response. This implicitly closes
+ * the established session. We chose this approach because we cannot easily
+ * mark the boundary between packets.
  *
  *
  * Partial parsing:
  *
  * It may happen that we received only staring part of some PDU from the
- * communication socket. In most cases, if we recognize this situation we
- * immediately return, waiting for rest of the PDU to arrive. But for packets
- * like agentx-Get-PDU, agentx-GetNext-PDU and agentx-GetBulk-PDU it could be
- * costly as they could hold many VarBinds. We don't want to process these
- * packet twice because it is a lot work. We parse all VarBinds until we hit the
- * first incomplete one. The logic behind this is to release as much as
- * possible space from receive buffer. When we hit the first incomplete VarBind,
- * we store information about the parsing state and move the header inside the
- * receive buffer.
- *
- * Transmit packet context
+ * communication socket. In most cases, if we recognize this situation, we
  *
  */
 
@@ -61,13 +42,13 @@ static uint update_packet_size(struct agentx_header *start, byte *end);
 const u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET };
 
 /*
- * snmp_header - store packet information into buffer
- * @h: pointer to created packet header in TX-buffer
+ * snmp_header - store packet header into buffer
+ * @h: pointer to created packet header in TX buffer
  * @type: created PDU type
  * @flags: set flags
  *
  * Payload length is set to zero legth. Padding is also zeroed. Real stored
- * flags are dependent on compile-time message byte-order configuration.
+ * flags depend on compile-time message byte order configuration.
  */
 static inline void
 snmp_header(struct agentx_header *h, enum agentx_pdu_types type, u8 flags)
@@ -81,7 +62,7 @@ snmp_header(struct agentx_header *h, enum agentx_pdu_types type, u8 flags)
 
 /*
  * snmp_blank_header - create header with no flags except byte order
- * @h: pointer to created header in TX-buffer
+ * @h: pointer to created header in TX buffer
  * @type: create PDU type
  *
  * Only flag possibly set may be packet byte order configuration.
@@ -96,7 +77,7 @@ snmp_blank_header(struct agentx_header *h, enum agentx_pdu_types type)
  * snmp_register_ack - handle registration response
  * @p: SNMP protocol instance
  * @res: header of agentx-Response-PDU
- * @mib: MIB subtree identifier
+ * @oid: MIB subtree Object Identifier
  */
 void
 snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, const struct oid *oid)
@@ -129,8 +110,8 @@ snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, const struc
  * @error: response PDU error fields value
  * @index: response PDU error index field value
  *
- * This function assumes that the buffer has enough space to fill in the AgentX
- * Response PDU. So it is the responsibility of the caller to provide that.
+ * This function assumes that the buffer has enough space to fill
+ * in the agentx-Response-PDU.
  */
 static void
 snmp_simple_response(struct snmp_proto *p, enum agentx_response_errs error, u16 index)
@@ -151,8 +132,8 @@ snmp_simple_response(struct snmp_proto *p, enum agentx_response_errs error, u16
  * @p: SNMP protocol instance
  * @oid: PDU OID description field value
  *
- * Other fields are filled based on @p configuration (timeout, subagent string
- * description)
+ * Other fields are filled based on @p configuration (timeout, subagent
+ * description).
  */
 static void
 open_pdu(struct snmp_proto *p, struct oid *oid)
@@ -165,11 +146,11 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
 
 #define TIMEOUT_SIZE sizeof(u32) /* 1B timeout, 3B zero padding */
 
-  /* Make sure that we have enough space in TX-buffer */
+  /* Make sure that we have enough space in TX buffer */
   uint s = AGENTX_HEADER_SIZE + TIMEOUT_SIZE + snmp_oid_size(oid) +
     snmp_str_size(cf->description);
-  if (snmp_tbuf_reserve(&c, s))
-    snmp_log("agentx-Open-PDU small buffer");
+
+  (void) snmp_tbuf_reserve(&c, s);
 
   struct agentx_header *h = (void *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
@@ -204,12 +185,15 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
  * @p: SNMP protocol instance
  * @oid: PDU notification Varbind name (OID)
  * @data: PDU Varbind payload
- * @size - PDU Varbind payload size
+ * @size: PDU Varbind payload size
  * @include_uptime: flag enabling inclusion of sysUpTime.0 OID
  */
 void
 snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime)
 {
+  if (!snmp_is_active(p))
+    return;
+
   sock *sk = p->sock;
 
   struct snmp_pdu c;
@@ -224,9 +208,8 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
   if (include_uptime)
     sz += UPTIME_SIZE;
 
-  /* Make sure that we have enough space in TX-buffer */
-  if (snmp_tbuf_reserve(&c, sz))
-    snmp_log("agentx-Notify-PDU small buffer");
+  /* Make sure that we have enough space in TX buffer */
+  (void) snmp_tbuf_reserve(&c, sz);
 
   struct agentx_header *h = (struct agentx_header *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
@@ -292,24 +275,23 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
  * @index: OIDs registration n_subid index
  * @type: register/unregister PDU type
  * @is_instance: flag enabling instance registration (used only for register)
- * @contid: context ID to register in (currently unsupported)
  *
  * Both register and unregister PDUs are capable of specifing a number of OIDs
- * by using pair of index and upper bound. The index (r.range_subid) points into
+ * by using pair of index and upper bound. The index (r.range_subid) points into
  * the OID's n_subid array to ID being threated as variable. The upper bound
- * (r.upper_bound) determins maximal value for n_subid selected by index.
- * The index and upper bound are passed as @index, and @bound respectively.
+ * (r.upper_bound) determins maximal value for n_subid selected by the index.
+ * The index and the upper bound are passed as @index, and @bound respectively.
  *
  * Zero value for @is_instance means we want to register/unregister OID as a MIB
  * subtree, for nonzero value we are registering MIB tree an instance (leaf).
+ * Full name of PDUs are agentx-Register-PDU and agentx-Unregister-PDU.
  *
  * This function in internal and shoulnd't be used outside the SNMP module,
  * see snmp_register() and snmp_unregister() functions.
  */
 static void
-un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, enum agentx_pdu_types type, u8 is_instance, uint UNUSED contid)
+un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, enum agentx_pdu_types type, u8 is_instance)
 {
-  /* used for agentx-Register-PDU and agentx-Unregister-PDU */
   const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
   sock *sk = p->sock;
   struct snmp_pdu c;
@@ -320,8 +302,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en
   uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) +
       ((bound > 1) ? BOUND_SIZE : 0);
 
-  if (snmp_tbuf_reserve(&c, sz))
-    snmp_log("agentx-Register-PDU small buffer");
+  (void) snmp_tbuf_reserve(&c, sz);
 
   struct agentx_header *h = (void *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
@@ -363,14 +344,13 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en
  * @bound: OIDs registration upper bound
  * @index: OIDs registration n_subid index
  * @is_instance: flag enabling instance registration
- * @contid: context ID to register in (currently unsupported)
  *
  * For more detailed description see un_register_pdu() function.
  */
 void
-snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 is_instance, uint contid)
+snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 is_instance)
 {
-  un_register_pdu(p, oid, bound, index, AGENTX_REGISTER_PDU, is_instance, contid);
+  un_register_pdu(p, oid, bound, index, AGENTX_REGISTER_PDU, is_instance);
 }
 
 /*
@@ -379,14 +359,13 @@ snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 i
  * @oid: OID to uregister
  * @bound: OIDs unregistration upper bound
  * @index: OIDs unregistration n_subid index
- * @contid: context ID to unregister from (currently unsupported)
  *
  * For more detailed description see un_register_pdu() function.
  */
 void
-snmp_unregister(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, uint contid)
+snmp_unregister(struct snmp_proto *p, struct oid *oid, u32 bound, uint index)
 {
-  un_register_pdu(p, oid, bound, index, AGENTX_UNREGISTER_PDU, 0, contid);
+  un_register_pdu(p, oid, bound, index, AGENTX_UNREGISTER_PDU, 0);
 }
 
 /*
@@ -402,8 +381,7 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason)
   snmp_pdu_context(&c, p, sk);
 
 #define REASON_SIZE sizeof(u32)
-  if (snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE + REASON_SIZE))
-    snmp_log("agentx-Close-PDU small buffer");
+  (void) snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE + REASON_SIZE);
 
   struct agentx_header *h = (void *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
@@ -424,7 +402,7 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason)
  * @p: SNMP protocol instance
  * @pkt_start: pointer to first byte of PDU
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static uint
 parse_close_pdu(struct snmp_proto *p, byte * const pkt_start)
@@ -440,22 +418,22 @@ parse_close_pdu(struct snmp_proto *p, byte * const pkt_start)
   {
     TRACE(D_PACKETS, "SNMP malformed agentx-Close-PDU, closing anyway");
     snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
-    snmp_set_state(p, SNMP_RESET);
-    return MIN(pkt_size + AGENTX_HEADER_SIZE, sizeof(struct agentx_close_pdu));
+    snmp_reset(p);
+    return 0;
   }
 
   if (!snmp_test_close_reason(pdu->reason))
   {
     TRACE(D_PACKETS, "SNMP invalid close reason %u", pdu->reason);
     snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
-    snmp_set_state(p, SNMP_RESET);
-    return pkt_size + AGENTX_HEADER_SIZE;
+    snmp_reset(p);
+    return 0;
   }
 
   enum agentx_close_reasons reason = (enum agentx_close_reasons) pdu->reason;
   TRACE(D_PACKETS, "SNMP close reason %u", reason);
   snmp_simple_response(p, AGENTX_RES_NO_ERROR, 0);
-  snmp_set_state(p, SNMP_RESET);
+  snmp_reset(p);
   return pkt_size + AGENTX_HEADER_SIZE;
 }
 
@@ -478,15 +456,15 @@ refresh_ids(struct snmp_proto *p, struct agentx_header *h)
  * @pkt_start: first byte of test set PDU
  * @size: number of bytes received from a socket
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static inline uint
 parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
 {
   TRACE(D_PACKETS, "SNMP received agentx-TestSet-PDU");
-  byte *pkt = pkt_start;  /* pointer to agentx-TestSet-PDU in RX-buffer */
+  byte *pkt = pkt_start;  /* pointer to agentx-TestSet-PDU in RX buffer */
   uint s; /* final packat size */
-  struct agentx_response *res; /* pointer to reponse in TX-buffer */
+  struct agentx_response *res; /* pointer to reponse in TX buffer */
 
   struct agentx_header *h = (void *) pkt;
   pkt += AGENTX_HEADER_SIZE;
@@ -495,8 +473,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
   struct snmp_pdu c;
   snmp_pdu_context(&c, p, sk);
 
-  if (snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE))
-    snmp_log("agentx-TestSet-PDU small buffer");
+  (void) snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE);
 
   res = prepare_response(p, &c);
 
@@ -534,7 +511,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
  * @pkt_start: pointer to first byte of on of set related PDU
  * @error: error status to use
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static uint
 parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_response_errs err)
@@ -554,8 +531,7 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons
 
   struct snmp_pdu c;
   snmp_pdu_context(&c, p, p->sock);
-  if (snmp_tbuf_reserve(&c, sizeof(struct agentx_response)))
-    snmp_log("parse_sets_pdu small buffer");
+  (void) snmp_tbuf_reserve(&c, sizeof(struct agentx_response));
 
   struct agentx_response *r = prepare_response(p, &c);
 
@@ -578,9 +554,9 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons
 /*
  * parse_commit_set_pdu - parse an agentx-CommitSet-PDU
  * @p: SNMP protocol instance
- * @pkt: pointer to first byte of PDU inside RX-buffer
+ * @pkt: pointer to first byte of PDU inside RX buffer
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static inline uint
 parse_commit_set_pdu(struct snmp_proto *p, byte *pkt)
@@ -594,7 +570,7 @@ parse_commit_set_pdu(struct snmp_proto *p, byte *pkt)
 /*
  * parse_undo_set_pdu - parse an agentx-UndoSet-PDU
  * @p: SNMP protocol instance
- * @pkt: pointer to first byte of PDU inside RX-buffer
+ * @pkt: pointer to first byte of PDU inside RX buffer
  *
  * Return number of bytes parsed from buffer.
  */
@@ -610,9 +586,9 @@ parse_undo_set_pdu(struct snmp_proto *p, byte *pkt)
 /*
  * parse_cleanup_set_pdu - parse an agentx-CleanupSet-PDU
  * @p: SNMP protocol instance
- * @pkt_start: pointer to first byte of PDU inside RX-buffer
+ * @pkt_start: pointer to first byte of PDU inside RX buffer
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static uint
 parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start)
@@ -639,7 +615,7 @@ parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start)
 }
 
 /*
- * space_for_response - check if TX-buffer has space for agentx-Response-PDU
+ * space_for_response - check if TX buffer has space for agentx-Response-PDU
  * @sk: communication socket owned by SNMP protocol instance
  *
  * In some cases we send only the AgentX header but if we want to signal an
@@ -657,10 +633,10 @@ space_for_response(const sock *sk)
 /**
  * parse_pkt - parse received AgentX packet
  * @p: SNMP protocol instance
- * @pkt: first byte of PDU inside RX-buffer
+ * @pkt: first byte of PDU inside RX buffer
  * @size: number of bytes received from a socket
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static uint
 parse_pkt(struct snmp_proto *p, byte *pkt, uint size)
@@ -685,7 +661,7 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size)
     TRACE(D_PACKETS, "SNMP received PDU is too long");
     snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
     snmp_reset(p);
-    return 0; /* no bytes parsed */
+    return 0;
   }
 
   /* This guarantees that we have the full packet already received */
@@ -768,9 +744,9 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size)
 /*
  * parse_response - parse an agentx-Response-PDU
  * @p: SNMP protocol instance
- * @res: pointer of agentx-Response-PDU header in RX-buffer
+ * @res: pointer of agentx-Response-PDU header in RX buffer
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static uint
 parse_response(struct snmp_proto *p, byte *res)
@@ -778,7 +754,6 @@ parse_response(struct snmp_proto *p, byte *res)
   struct agentx_response *r = (void *) res;
   struct agentx_header *h = (void *) r;
 
-  // todo reject not compiled byte order
   uint pkt_size = LOAD_U32(h->payload);
 
   switch (r->error)
@@ -812,7 +787,8 @@ parse_response(struct snmp_proto *p, byte *res)
     case AGENTX_RES_PROCESSING_ERR:
     default:
       TRACE(D_PACKETS, "SNMP agentx-Response-PDU with unexepected error %u", r->error);
-      snmp_stop(p);
+      //snmp_stop(p);
+      snmp_reset(p);
       break;
   }
 
@@ -832,9 +808,9 @@ snmp_register_mibs(struct snmp_proto *p)
 /*
  * do_response - act on agentx-Response-PDU and protocol state
  * @p: SNMP protocol instance
- * @pkt: RX-buffer with PDU bytes
+ * @pkt: RX buffer with PDU bytes
  *
- * Return number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX buffer.
  */
 static void
 do_response(struct snmp_proto *p, byte *pkt)
@@ -910,8 +886,7 @@ void
 snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid)
 {
   uint vb_hdr_size = snmp_varbind_hdr_size_from_oid(oid);
-  if (snmp_tbuf_reserve(c, vb_hdr_size))
-    snmp_log("SNMP vb_to_tx small buffer");
+  (void) snmp_tbuf_reserve(c, vb_hdr_size);
 
   ASSERT(c->size >= vb_hdr_size);
   struct agentx_varbind *vb = (struct agentx_varbind *) c->buffer;
@@ -935,12 +910,22 @@ snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid)
   c->sr_vb_start = vb;
 }
 
+/*
+ * snmp_fix_vb - fix VarBind's name OID byte order
+ * @vb: VarBind to use
+ */
+void
+snmp_fix_vb(struct agentx_varbind *vb)
+{
+  snmp_oid_copy(&vb->name, &vb->name);
+}
+
 /*
  * update_packet_size - set PDU size
  * @start - pointer to PDU data start (excluding header size)
  * @end - pointer after the last PDU byte
  *
- * Return number of bytes in TX-buffer (including header size).
+ * Return number of bytes in TX buffer (including header size).
  */
 static inline uint
 update_packet_size(struct agentx_header *start, byte *end)
@@ -985,18 +970,6 @@ response_err_ind(struct snmp_proto *p, struct agentx_response *res, enum agentx_
     STORE_U16(res->index, 0);
 }
 
-static inline uint
-parse_gets_error(struct snmp_proto *p, struct snmp_pdu *c, uint len)
-{
-  TRACE(D_PACKETS, "SNMP error %u while parsing gets PDU", c->error);
-  if (c->index > UINT16_MAX)
-    snmp_simple_response(p, AGENTX_RES_GEN_ERROR, UINT16_MAX);
-  else
-    snmp_simple_response(p, AGENTX_RES_GEN_ERROR, c->index);
-
-  return len + AGENTX_HEADER_SIZE;
-}
-
 /*
  * AgentX GetPDU, GetNextPDU and GetBulkPDU
  */
@@ -1005,18 +978,12 @@ parse_gets_error(struct snmp_proto *p, struct snmp_pdu *c, uint len)
 void
 snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk)
 {
-  snmp_log("snmp_get_pdu()");
-
   struct mib_leaf *leaf;
   leaf = snmp_walk_init(p->mib_tree, walk, o_start, c);
 
-  snmp_log("found node %p", leaf);
-
   enum snmp_search_res res;
   res = snmp_walk_fill(leaf, walk, c);
 
-  snmp_log("fill result %u", res);
-
   if (res != SNMP_SEARCH_OK)
     snmp_set_varbind_type(c->sr_vb_start, snmp_search_res_to_type(res));
 }
@@ -1060,7 +1027,6 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c)
 
   if ((sz = snmp_oid_size(start)) > pkt_size)
   {
-    snmp_log("load_oids start %u / %u", sz, pkt_size);
     c->error = AGENTX_RES_PARSE_ERROR;
     *pkt_ptr = pkt;
     *pkt_sz = pkt_size;
@@ -1072,7 +1038,6 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c)
   const struct oid *end = (const struct oid *) pkt;
   if ((sz = snmp_oid_size(end)) > pkt_size)
   {
-    snmp_log("load_oids end %u / %u", sz, pkt_size);
     c->error = AGENTX_RES_PARSE_ERROR;
     *pkt_ptr = pkt;
     *pkt_sz = pkt_size;
@@ -1081,6 +1046,7 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c)
 
   ADVANCE(pkt, pkt_size, sz);
 
+  // TODO: this does not work
   if (!snmp_is_oid_empty(end) &&
       snmp_oid_compare(start, end) > 0)
   {
@@ -1106,13 +1072,11 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c)
  *
  * Gets PDUs are agentx-Get-PDU, agentx-GetNext-PDU, agentx-GetBulk-PDU.
  *
- * Return number of bytes parsed from RX-buffer
+ * Return number of bytes parsed from RX buffer
  */
 static uint
 parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
 {
-  snmp_log("parse_gets_pdu msg");
-  // TODO checks for c.size underflow
   struct mib_walk_state walk;
   byte *pkt = pkt_start;
 
@@ -1125,18 +1089,20 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
   snmp_pdu_context(&c, p, sk);
 
   /*
-   * Get-Bulk processing stops if all the varbind have type END_OF_MIB_VIEW
-   * has_any is true if some varbind has type other than END_OF_MIB_VIEW
+   * Get-Bulk processing stops if all the varbind have type endOfMibView
+   * has_any is true if some varbind has type other than endOfMibView
    */
   struct agentx_bulk_state bulk_state = { 0 };
   if (h->type == AGENTX_GET_BULK_PDU)
   {
+    die("bulk");
+
+#if 0
     if (pkt_size < sizeof(struct agentx_getbulk))
     {
-      snmp_log("parse_gets GetBulkPDU prepare");
-      c.error = AGENTX_RES_PARSE_ERROR;
-      c.index = 0;
-      return parse_gets_error(p, &c, pkt_size);
+      snmp_simple_response(p, AGENTX_RES_PARSE_ERROR, 0);
+      snmp_reset(p);
+      return pkt_size + AGENTX_HEADER_SIZE;
     }
 
     struct agentx_getbulk *bulk_info = (void *) pkt;
@@ -1152,6 +1118,7 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
       .repetition = 0,
       .has_any = 0,
     };
+#endif
   }
 
   struct agentx_response *response_header = prepare_response(p, &c);
@@ -1165,8 +1132,10 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
     const struct oid *start_rx;
     if (!(start_rx = snmp_load_oids(&pkt, &pkt_size, &c)))
     {
-      snmp_log("snmp_load_oid ends with an error");
-      return parse_gets_error(p, &c, pkt_size);
+      snmp_simple_response(p, c.error,
+       (c.index > UINT16_MAX) ? UINT16_MAX : c.index);
+      snmp_reset(p);
+      return pkt_size + AGENTX_HEADER_SIZE;
     }
 
     switch (h->type)
@@ -1195,23 +1164,24 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
 
   lp_restore(tmp_linpool, &tmps);
 
+#if 0
   if (h->type == AGENTX_GET_BULK_PDU)
   {
     // TODO: an error for now
+    die("bulk");
   }
+#endif
 
   /* We update the error, index pair on the beginning of the packet. */
   response_err_ind(p, response_header, c.error, c.index + 1);
   uint s = update_packet_size(&response_header->h, c.buffer);
 
-  /* We send the message in TX-buffer. */
+  /* We send the message in TX buffer. */
   sk_send(sk, s);
 
-  snmp_log("gets send %t", current_time());
-
   // TODO think through the error state
 
-  /* number of bytes parsed from RX-buffer */
+  /* number of bytes parsed from RX buffer */
   return pkt - pkt_start;
 }
 
@@ -1246,7 +1216,7 @@ snmp_stop_subagent(struct snmp_proto *p)
 }
 
 /*
- * snmp_rx - handle received PDUs in RX-buffer in normal operation
+ * snmp_rx - handle received PDUs in RX buffer in normal operation
  * @sk: communication socket
  * @size: number of bytes received
  */
@@ -1268,9 +1238,9 @@ snmp_rx(sock *sk, uint size)
     size -= parsed_len;
   }
 
-  /* We flush the RX-buffer on errors */
+  /* We flush the RX buffer on errors */
   if (!snmp_is_active(p) || pkt_start == end)
-    return 1; /* The whole RX-buffer was consumed */
+    return 1; /* The whole RX buffer was consumed */
 
   /* Incomplete packet parsing */
   memmove(sk->rbuf, pkt_start, size);
@@ -1279,21 +1249,20 @@ snmp_rx(sock *sk, uint size)
 }
 
 /*
- * snmp_tx - handle TX-buffer
+ * snmp_tx - handle TX buffer
  * @sk: communication socket owned by SNMP protocol instance
  *
  * The snmp_tx hook is used only to delay the processing in cases we don't have
- * enough space in TX-buffer. Therefore we simply call the snmp_rx hook.
+ * enough space in TX buffer. Therefore we simply call the snmp_rx hook.
  */
 void
 snmp_tx(sock *sk)
 {
-  snmp_log("snmp_tx()");
   /* We still not have enough space */
   if (!space_for_response(sk))
     return;
 
-  /* There is nothing to process, no bytes in RX-buffer */
+  /* There is nothing to process, no bytes in RX buffer */
   if (sk_tx_buffer_empty(sk))
     return;
 
@@ -1326,7 +1295,6 @@ snmp_ping(struct snmp_proto *p)
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
   snmp_blank_header(h, AGENTX_PING_PDU);
   p->packet_id++;
-  snmp_log("incrementing packet_id to %u (ping)", p->packet_id);
   snmp_session(p, h);
 
   /* sending only header */
@@ -1335,27 +1303,12 @@ snmp_ping(struct snmp_proto *p)
   sk_send(sk, s);
 }
 
-/**
- * snmp_search_check_end_oid - check if oid is before SearchRange end
- *
- * @found: best oid found in MIB tree
- * @bound: upper bound specified in SearchRange
- *
- * check if found oid meet the SearchRange upper bound condition in
- * lexicographical order, returns boolean value
- */
-int
-snmp_search_check_end_oid(const struct oid *found, const struct oid *bound)
-{
-  if (snmp_is_oid_empty(bound))
-    return 1;
-
-  return (snmp_oid_compare(found, bound) < 0);
-}
-
 /*
- * snmp_tbuf_reserve - TODO
+ * snmp_tbuf_reserve - conditionally grow the TX buffer
+ * @c: transmit PDU context
+ * @size: size to make available
  *
+ * Return non-zero if the buffer was relocated.
  */
 int
 snmp_tbuf_reserve(struct snmp_pdu *c, size_t size)
@@ -1365,16 +1318,15 @@ snmp_tbuf_reserve(struct snmp_pdu *c, size_t size)
     struct snmp_proto *p = c->p;
     sock *sk = p->sock;
 
-    int diff;
+    int start_diff;
     if (c->sr_vb_start != NULL)
-      diff = (char *) c->sr_vb_start - (char *) sk->tbuf;
+      start_diff = (char *) c->sr_vb_start - (char *) sk->tbuf;
 
-    snmp_log("snmp_tbuf_reserve()");
     sk_set_tbsize(sk, sk->tbsize + 2048);
     c->size += 2048;
 
     if (c->sr_vb_start != NULL)
-      c->sr_vb_start = (struct agentx_varbind *) (sk->tbuf + diff);
+      c->sr_vb_start = (struct agentx_varbind *) (sk->tbuf + start_diff);
 
     return 1;
   }
@@ -1387,7 +1339,7 @@ snmp_tbuf_reserve(struct snmp_pdu *c, size_t size)
  * @p: SNMP protocol instance
  * @c: transmit PDU context to use
  *
- * Prepare known parts of AgentX packet header into the TX-buffer held by @c.
+ * Prepare known parts of AgentX packet header into the TX buffer held by @c.
  */
 static struct agentx_response *
 prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
index 109da6b765136bbc9fe6c61e0ab1019280e293af..3c90da14029bbe4c5feb9aca9450434147ffb268 100644 (file)
@@ -357,10 +357,10 @@ struct snmp_packet_info {
 };
 
 int snmp_rx(sock *sk, uint size);
+void snmp_tx(sock *sk);
 int snmp_rx_stop(sock *sk, uint size);
-void snmp_down(struct snmp_proto *p);
-void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance, uint contid);
-void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len, uint contid);
+void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance);
+void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len);
 void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime);
 
 int snmp_tbuf_reserve(struct snmp_pdu *c, size_t bytes);
@@ -378,12 +378,4 @@ u8 snmp_get_mib_class(const struct oid *oid);
 
 void snmp_register_mibs(struct snmp_proto *p);
 
-/* MIB modules */
-
-#if 1
-#define snmp_log(...) log(L_INFO "SNMP " __VA_ARGS__)
-#else
-#define snmp_log(...) do { } while(0)
-#endif
-
 #endif