mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
SNMP: Documentation improvements
This commit is contained in:
parent
c18e6dd58d
commit
a6a07ffb19
@ -8,7 +8,39 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple Network Management Protocol State Machine
|
||||
* DOC: Simple Network Management Protocol
|
||||
*
|
||||
* The SNMP protocol is divided into several parts: |snmp.c| which implements
|
||||
* the BIRD intergration, |subagent.c| contains functions for creating and
|
||||
* parsing packets, |bgp_mib.c| takes care of the bgp MIB subtree of standard
|
||||
* BGP4-MIB and |snmp_utils.c| which is collections of helper functions for
|
||||
* working with OIDs, VarBinds.
|
||||
*
|
||||
* Althrough called SNMP the BIRD does not implement SNMP directly but acts as
|
||||
* an AgentX subagent. AgentX subagent connects to AgentX master agent that
|
||||
* processes incomming SNMP requests and passes them down to the correct
|
||||
* subagent. Therefore you need also a running master agent somewhere.
|
||||
* Advantages of this design are that you are capable of doing aggregation of
|
||||
* statuses of multiple BIRDs at the master agent level and much simpler
|
||||
* implementation.
|
||||
*
|
||||
* Before any of the SNMP request could be processed, the SNMP need to
|
||||
* established AgentX session with the master agent and need to register all
|
||||
* subtrees to make them accessible from the master agent. The establishement of
|
||||
* the of session is handled by snmp_start(), snmp_start_locked() and
|
||||
* snmp_start_subagent(). Then we register all MIBs from configuration in
|
||||
* snmp_register_mibs().
|
||||
*
|
||||
* The AgentX request are handled only during MIB subtree registrations and
|
||||
* after then on established session (in states SNMP_REGISTER and SNMP_CONN, see
|
||||
* below). It is also guaranteed that no request is received before MIB subtree
|
||||
* registration because the specific subagent is not authoratitave and also the
|
||||
* master agent has no info about MIB subtree supported by subagent. The AgentX
|
||||
* requests are handled by function snmp_rx() in |subagent.c|.
|
||||
*
|
||||
*
|
||||
*
|
||||
* SNMP State Machine
|
||||
*
|
||||
* States with main transitions
|
||||
*
|
||||
|
@ -28,23 +28,34 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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 also 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()
|
||||
* to be called. The socket's tx_hook is called when the TX-buffer is empty,
|
||||
* meaning our response (agentx-Response-PDU) was send.
|
||||
*
|
||||
* 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()
|
||||
* to be called. The socket's tx_hook is called when the TX-buffer is empty,
|
||||
* meaning our response (agentx-Response-PDU) was send.
|
||||
*
|
||||
*
|
||||
* 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. In these cases we process.
|
||||
* 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
|
||||
*
|
||||
@ -1498,6 +1509,7 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
|
||||
{
|
||||
res = p->last_header;
|
||||
p->last_header = NULL;
|
||||
p->last_size = 0;
|
||||
}
|
||||
else
|
||||
res = response_header;
|
||||
@ -1520,6 +1532,7 @@ partial:
|
||||
STORE_U32(h->payload, pkt_size);
|
||||
*skip = AGENTX_HEADER_SIZE;
|
||||
p->last_header = h;
|
||||
p->last_size = c.buffer - sk->tpos;
|
||||
|
||||
/* number of bytes parsed from RX-buffer */
|
||||
ret = pkt - pkt_start;
|
||||
@ -1632,7 +1645,16 @@ snmp_ping(struct snmp_proto *p)
|
||||
snmp_pdu_context(&c, sk);
|
||||
|
||||
if (c.size < AGENTX_HEADER_SIZE)
|
||||
snmp_manage_tbuf(p, &c);
|
||||
return;
|
||||
|
||||
int unused = (sk->tbsize - (sk->tpos - sk->tbuf)) - (p->last_size + AGENTX_HEADER_SIZE);
|
||||
if (p->last_header && unused >= 0)
|
||||
{
|
||||
|
||||
}
|
||||
else if (p->last_header)
|
||||
{
|
||||
}
|
||||
|
||||
struct agentx_header *h = (struct agentx_header *) c.buffer;
|
||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||
|
Loading…
Reference in New Issue
Block a user