0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-31 14:11:54 +00:00

Testing Notify-PDU

This commit is contained in:
Vojtech Vilimek 2023-09-04 09:25:51 +02:00
parent 3c718d162c
commit df28d1cbe8
4 changed files with 589 additions and 211 deletions

View File

@ -70,9 +70,7 @@ snmp_bgp_register(struct snmp_proto *p)
add_tail(&p->register_queue, &registering->n);
p->register_to_ack++;
/* Function declartion:
* snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance);
*/
/* snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance) */
snmp_register(p, oid, 0, 1, 0);
}
}
@ -114,11 +112,10 @@ bgp_get_candidate(u32 field)
};
/*
* First value is in secord cell of array translation_table (as the
* First value is in secord cell of array translation_table, as the
* SNMP_BPG_IDENTIFIER == 1
*/
if (field > 0 &&
field <= sizeof(translation_table)/sizeof(translation_table[0]) - 1)
if (field > 0 && field <= sizeof(translation_table) / sizeof(translation_table[0]) - 1)
return translation_table[field];
if (field == 0)
return BGP_INTERNAL_INVALID;
@ -193,6 +190,7 @@ print_bgp_record_all(struct snmp_proto *p)
snmp_log("dumping watched end");
}
/**
* snmp_bgp_state - linearize oid from BGP4-MIB
* @oid: prefixed object identifier from BGP4-MIB::bgp subtree
@ -402,7 +400,7 @@ update_bgp_oid(struct oid *oid, u8 state)
state == BGP_INTERNAL_NO_VALUE)
return oid;
/* No need to reallocate anything if the OID is has same lin. state */
/* No need to reallocate anything if the OID has same lin. state */
if (snmp_bgp_state(oid) == state)
{
if (state >= BGP_INTERNAL_IDENTIFIER &&
@ -537,6 +535,7 @@ update_bgp_oid(struct oid *oid, u8 state)
default:
/* intentionally left blank */
break;
//die("update unavailable");
}
return oid;
@ -590,10 +589,7 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, const struct oid
if (cmp < 0 || (cmp == 0 && snmp_is_oid_empty(o_end)))
{
snmp_log("ip4_less() returned true");
struct oid *o = mb_allocz(p->p.pool, snmp_oid_sizeof(9));
o->n_subid = 9;
memcpy(o, o_start, snmp_oid_size(o_start));
struct oid *o = snmp_oid_duplicate(p->p.pool, o_start);
snmp_oid_ip4_index(o, 5, net4_prefix(&net));
return o;
@ -627,7 +623,7 @@ UNUSED, u8 current_state)
snmp_oid_dump(o_start);
next_state = snmp_bgp_next_state(next_state);
/* We search in next state is done from beginning. */
/* The search in next state is done from beginning. */
o_start->ids[5] = o_start->ids[6] = o_start->ids[7] = o_start->ids[8] = 0;
o_start->include = 1;
@ -647,7 +643,6 @@ UNUSED, u8 current_state)
static int
snmp_bgp_find_next_oid(struct snmp_proto *p, struct oid *oid, uint UNUSED contid)
{
// TODO add o_end paramenter for faster searches
ip4_addr ip4 = ip4_from_oid(oid);
//ip_add4 dest = ip4_from_u32(0xFFFFFFFF);
@ -722,7 +717,7 @@ snmp_bgp_search_dynamic(struct snmp_proto *p, struct oid **searched, const struc
oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0;
}
if (next_state <= end_state)
if (next_state < BGP_INTERNAL_END && next_state <= end_state)
{
*searched = oid;
return SNMP_SEARCH_OK;
@ -740,6 +735,11 @@ snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *
struct oid *oid = *searched;
snmp_log("snmp_bgp_search2() with state %s [%d]", debug_bgp_states[bgp_state], bgp_state);
if (bgp_state == BGP_INTERNAL_END)
{
return SNMP_SEARCH_NO_OBJECT;
}
/* TODO remove todo below, then remove this code */
if (is_dynamic(bgp_state))
{
@ -773,7 +773,8 @@ snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *
oid = *searched = update_bgp_oid(*searched, bgp_state);
if (oid->n_subid == 3 && oid->ids[2] >= SNMP_BGP_VERSION &&
oid->ids[2] <= SNMP_BGP_LOCAL_AS)
oid->ids[2] <= SNMP_BGP_LOCAL_AS && bgp_state != BGP_INTERNAL_END)
//oid->ids[2] <= SNMP_BGP_LOCAL_AS && bgp_state != BGP_INTERNAL_END)
{
snmp_log("oid matches static state");
oid->include = 0;
@ -789,8 +790,8 @@ struct oid *
snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid UNUSED)
{
u8 start_state = snmp_bgp_state(o_start);
//u8 state_curr = snmp_bgp_state(o_start);
//u8 state_end = (o_end) ? snmp_bgp_state(o_end) : 0;
// print debugging information
print_bgp_record_all(p);
if (o_start->include && snmp_bgp_has_value(start_state) &&
@ -808,7 +809,7 @@ snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, ui
return search_bgp_dynamic(p, o_start, o_end, contid, start_state);
}
/* o_start->include == 0 */
/* o_start is not inclusive */
u8 next_state = snmp_bgp_next_state(start_state);
// TODO more checks ?!?
@ -844,6 +845,8 @@ bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
}
snmp_log(" -> ip addr %I", addr);
// TODO XXX deal with possible change of (remote) ip; BGP should restart and
// disappear
struct snmp_bgp_peer *pe = HASH_FIND(p->bgp_hash, SNMP_HASH, addr);
struct bgp_proto *bgp_proto = NULL;

View File

@ -7,6 +7,68 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*/
/**
* Simple Network Management Protocol State Machine
*
* States with main transitions
*
*
* +-----------------+
* | SNMP_INIT | entry state after call snmp_start()
* +-----------------+
* |
* | acquiring object lock for communication socket
* V
* +-----------------+
* | SNMP_LOCKED | object lock aquired
* +-----------------+
* |
* | opening communaiton socket
* V
* +-----------------+
* | SNMP_OPEN | socket created, starting subagent
* +-----------------+
* |
* | BIRD recieve response for Open-PDU
* V
* +-----------------+
* | SNMP_REGISTER | session was established, subagent registers MIBs
* +-----------------+
* |
* | subagent recieved responses for all registration requests
* V
* +-----------------+
* | SNMP_CONN | everything is set
* +-----------------+
* |
* | function snmp_shutdown() is called, BIRD sends Close-PDU
* V
* +-----------------+
* | SNMP_STOP | waiting for response
* +-----------------+
* |
* | cleaning old state information
* V
* +-----------------+
* | SNMP_DOWN | session is closed
* +-----------------+
*
*
* 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, reciept of
* Close-PDU) SNMP cleans the session information and message queue and goes
* back to the SNMP_LOCKED state.
*
* Reconfiguration is done in similar fashion to BGP, the reconfiguration
* request is declined, the protocols is stoped and started with new
* configuration.
*
*/
#include "nest/bird.h"
#include "nest/cli.h"
#include "nest/locks.h"
@ -26,6 +88,15 @@ static void snmp_start_locked(struct object_lock *lock);
static int snmp_shutdown(struct proto *P);
static const char * const snmp_state[] = {
[SNMP_ERR] = "SNMP ERROR",
[SNMP_INIT] = "SNMP INIT",
[SNMP_LOCKED] = "SNMP LOCKED",
[SNMP_OPEN] = "SNMP CONNECTION OPENED",
[SNMP_REGISTER] = "SNMP REGISTERING MIBS",
[SNMP_CONN] = "SNMP CONNECTED",
[SNMP_STOP] = "SNMP STOPING",
[SNMP_DOWN] = "SNMP DOWN",
/*
[SNMP_ERR] = "SNMP ERROR",
[SNMP_DELAY] = "SNMP DELAY",
[SNMP_INIT] = "SNMP INIT",
@ -34,6 +105,7 @@ static const char * const snmp_state[] = {
[SNMP_STOP] = "SNMP STOP",
[SNMP_DOWN] = "SNMP DOWN",
[SNMP_LISTEN] = "SNMP LISTEN",
*/
};
static struct proto *
@ -110,10 +182,12 @@ snmp_startup(struct snmp_proto *p)
{
//snmp_log("changing proto_snmp state to INIT");
if (p->state == SNMP_CONN ||
p->state == SNMP_REGISTER)
if (p->state == SNMP_LOCKED ||
p->state == SNMP_OPEN ||
p->state == SNMP_REGISTER ||
p->state == SNMP_CONN)
{
snmp_log("startup() with invalid state %u", p->state);
snmp_log("startup() already in connected state %u", p->state);
return;
}
@ -151,6 +225,8 @@ snmp_start_locked(struct object_lock *lock)
snmp_log("snmp_start_locked() - lock acquired; preparing socket");
struct snmp_proto *p = lock->data;
p->state = SNMP_LOCKED;
sock *s = sk_new(p->p.pool);
s->type = SK_TCP_ACTIVE;
s->saddr = p->local_ip;
@ -185,6 +261,9 @@ snmp_connected(sock *sk)
{
struct snmp_proto *p = sk->data;
snmp_log("snmp_connected() connection created");
p->state = SNMP_OPEN;
byte *buf UNUSED = sk->rpos;
sk->rx_hook = snmp_rx;
@ -392,8 +471,8 @@ snmp_shutdown(struct proto *P)
tm_stop(p->ping_timer);
/* connection established -> close the connection */
if (p->state == SNMP_CONN ||
p->state == SNMP_REGISTER)
if (p->state == SNMP_REGISTER ||
p->state == SNMP_CONN)
{
p->state = SNMP_STOP;
@ -407,7 +486,6 @@ snmp_shutdown(struct proto *P)
return PS_STOP;
}
/* no connection to close */
else
{
@ -435,3 +513,4 @@ snmp_build(void)
{
proto_build(&proto_snmp);
}

View File

@ -31,6 +31,17 @@
enum snmp_proto_state {
SNMP_ERR = 0,
SNMP_INIT = 1,
SNMP_LOCKED,
SNMP_OPEN,
SNMP_REGISTER,
SNMP_CONN,
SNMP_STOP,
SNMP_DOWN,
/*
SNMP_ERR = 0,
SNMP_DELAY,
SNMP_INIT,
SNMP_REGISTER,
@ -38,6 +49,8 @@ enum snmp_proto_state {
SNMP_STOP,
SNMP_DOWN,
SNMP_LISTEN,
SNMP_RESET,
*/
};
/* hash table macros */

File diff suppressed because it is too large Load Diff