ldpd: Add support for read-only snmp mib objects (excluding statistics)

Add support for read-only snmp mib objects as described in RFC 3815,
excluding statistics.

Signed-off-by: Lynne Morrison <lynne@voltanet.io>
Signed-off-by: Karen Schoener <karen@voltanet.io>
This commit is contained in:
Karen Schoener 2021-02-24 17:24:35 -05:00
parent e024c08200
commit f9a4d683dc
8 changed files with 1190 additions and 12 deletions

View File

@ -127,15 +127,13 @@ static struct quagga_signal_t lde_signals[] =
void
lde(void)
{
struct thread thread;
#ifdef HAVE_SETPROCTITLE
setproctitle("label decision engine");
#endif
ldpd_process = PROC_LDE_ENGINE;
log_procname = log_procnames[PROC_LDE_ENGINE];
master = thread_master_create(NULL);
master = frr_init();
/* setup signal handler */
signal_init(master, array_size(lde_signals), lde_signals);
@ -157,9 +155,12 @@ lde(void)
/* create base configuration */
ldeconf = config_new_empty();
/* Fetch next active thread. */
struct thread thread;
while (thread_fetch(master, &thread))
thread_call(&thread);
/* NOTREACHED */
return;
}
void
@ -566,6 +567,9 @@ lde_dispatch_parent(struct thread *thread)
memcpy(&init, imsg.data, sizeof(init));
lde_init(&init);
break;
case IMSG_AGENTX_ENABLED:
ldp_agentx_enabled();
break;
case IMSG_RECONF_CONF:
if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
NULL)

1087
ldpd/ldp_snmp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -86,6 +86,30 @@ static struct imsgev *iev_lde, *iev_lde_sync;
static pid_t ldpe_pid;
static pid_t lde_pid;
static struct frr_daemon_info ldpd_di;
DEFINE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm))
static void ldp_load_module(const char *name)
{
const char *dir;
dir = ldpd_di.module_path ? ldpd_di.module_path : frr_moduledir;
char moderr[256];
struct frrmod_runtime *module;
module = frrmod_load(name, dir, moderr, sizeof(moderr));
if (!module) {
fprintf(stderr, "%s: failed to load %s", __func__, name);
log_warnx("%s: failed to load %s", __func__, name);
}
}
void ldp_agentx_enabled(void)
{
ldp_load_module("snmp");
hook_call(ldp_register_mib, master);
}
enum ldpd_process ldpd_process;
#define LDP_DEFAULT_CONFIG "ldpd.conf"
@ -94,8 +118,6 @@ enum ldpd_process ldpd_process;
/* Master of threads. */
struct thread_master *master;
static struct frr_daemon_info ldpd_di;
/* ldpd privileges */
static zebra_capabilities_t _caps_p [] =
{
@ -1343,6 +1365,9 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
ldpe_reset_ds_nbrs();
}
if (ldpd_process == PROC_LDP_ENGINE)
ldpe_set_config_change_time();
conf->flags = xconf->flags;
}

View File

@ -161,6 +161,7 @@ enum imsg_type {
IMSG_RLFA_REG,
IMSG_RLFA_UNREG_ALL,
IMSG_RLFA_LABELS,
IMSG_AGENTX_ENABLED,
};
struct ldpd_init {
@ -434,6 +435,7 @@ struct ldp_stats {
uint32_t labelrel_rcvd;
uint32_t labelabreq_sent;
uint32_t labelabreq_rcvd;
};
struct l2vpn_if {
@ -562,6 +564,7 @@ struct ldpd_conf {
uint16_t trans_pref;
uint16_t wait_for_sync_interval;
int flags;
time_t config_change_time;
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(ldpd_conf)
@ -683,6 +686,8 @@ struct ctl_nbr {
int nbr_state;
struct ldp_stats stats;
int flags;
uint16_t max_pdu_len;
uint16_t hold_time_remaining;
};
struct ctl_rt {
@ -891,4 +896,8 @@ int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response *
(__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_INTFACELOCAL))
#endif
DECLARE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm))
extern void ldp_agentx_enabled(void);
#endif /* _LDPD_H_ */

View File

@ -33,6 +33,7 @@
#include "memory.h"
#include "privs.h"
#include "sigevent.h"
#include "libfrr.h"
static void ldpe_shutdown(void);
static int ldpe_dispatch_main(struct thread *);
@ -103,15 +104,13 @@ char *pkt_ptr; /* packet buffer */
void
ldpe(void)
{
struct thread thread;
#ifdef HAVE_SETPROCTITLE
setproctitle("ldp engine");
#endif
ldpd_process = PROC_LDP_ENGINE;
log_procname = log_procnames[ldpd_process];
master = thread_master_create(NULL);
master = frr_init();
/* setup signal handler */
signal_init(master, array_size(ldpe_signals), ldpe_signals);
@ -133,9 +132,12 @@ ldpe(void)
/* create base configuration */
leconf = config_new_empty();
/* Fetch next active thread. */
struct thread thread;
while (thread_fetch(master, &thread))
thread_call(&thread);
/* NOTREACHED */
return;
}
void
@ -387,6 +389,9 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(&init, imsg.data, sizeof(init));
ldpe_init(&init);
break;
case IMSG_AGENTX_ENABLED:
ldp_agentx_enabled();
break;
case IMSG_CLOSE_SOCKETS:
af = imsg.hdr.peerid;
@ -1073,3 +1078,10 @@ ldpe_check_filter_af(int af, struct ldpd_af_conf *af_conf,
if (strcmp(af_conf->acl_thello_accept_from, filter_name) == 0)
ldpe_remove_dynamic_tnbrs(af);
}
void
ldpe_set_config_change_time(void)
{
/* SNMP update time when ever there is a config change */
leconf->config_change_time = time(NULL);
}

View File

@ -216,6 +216,7 @@ void ldpe_nbr_ctl(struct ctl_conn *);
void ldpe_ldp_sync_ctl(struct ctl_conn *);
void mapping_list_add(struct mapping_head *, struct map *);
void mapping_list_clr(struct mapping_head *);
void ldpe_set_config_change_time(void);
/* interface.c */
struct iface *if_new(const char *);
@ -266,6 +267,8 @@ struct nbr *nbr_new(struct in_addr, int, int, union ldpd_addr *,
uint32_t);
void nbr_del(struct nbr *);
struct nbr *nbr_find_ldpid(uint32_t);
struct nbr *nbr_get_first_ldpid(void);
struct nbr *nbr_get_next_ldpid(uint32_t);
struct nbr *nbr_find_addr(int, union ldpd_addr *);
struct nbr *nbr_find_peerid(uint32_t);
int nbr_adj_count(struct nbr *, int);
@ -318,4 +321,6 @@ void ldpe_l2vpn_exit(struct l2vpn *);
void ldpe_l2vpn_pw_init(struct l2vpn_pw *);
void ldpe_l2vpn_pw_exit(struct l2vpn_pw *);
DECLARE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state), (nbr, old_state))
#endif /* _LDPE_H_ */

View File

@ -26,6 +26,8 @@
#include "lde.h"
#include "log.h"
DEFINE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state), (nbr, old_state))
static __inline int nbr_id_compare(const struct nbr *, const struct nbr *);
static __inline int nbr_addr_compare(const struct nbr *,
const struct nbr *);
@ -158,6 +160,8 @@ nbr_fsm(struct nbr *nbr, enum nbr_event event)
&nbr->id, nbr_state_name(old_state),
nbr_state_name(nbr->state));
hook_call(ldp_nbr_state_change, nbr, old_state);
if (nbr->state == NBR_STA_OPER) {
gettimeofday(&now, NULL);
nbr->uptime = now.tv_sec;
@ -354,6 +358,23 @@ nbr_find_ldpid(uint32_t lsr_id)
return (RB_FIND(nbr_id_head, &nbrs_by_id, &n));
}
struct nbr *
nbr_get_first_ldpid()
{
return (RB_MIN(nbr_id_head, &nbrs_by_id));
}
struct nbr *
nbr_get_next_ldpid(uint32_t lsr_id)
{
struct nbr *nbr;
nbr = nbr_find_ldpid(lsr_id);
if (nbr)
return (RB_NEXT(nbr_id_head, nbr));
return NULL;
}
struct nbr *
nbr_find_addr(int af, union ldpd_addr *addr)
{
@ -831,14 +852,20 @@ nbr_to_ctl(struct nbr *nbr)
nctl.af = nbr->af;
nctl.id = nbr->id;
nctl.laddr = nbr->laddr;
nctl.lport = nbr->tcp->lport;
nctl.lport = nbr->tcp ? nbr->tcp->lport : 0;
nctl.raddr = nbr->raddr;
nctl.rport = nbr->tcp->rport;
nctl.rport = nbr->tcp ? nbr->tcp->rport : 0;
nctl.auth_method = nbr->auth.method;
nctl.holdtime = nbr->keepalive;
nctl.nbr_state = nbr->state;
nctl.stats = nbr->stats;
nctl.flags = nbr->flags;
nctl.max_pdu_len = nbr->max_pdu_len;
if (nbr->keepalive_timer)
nctl.hold_time_remaining =
thread_timer_remain_second(nbr->keepalive_timer);
else
nctl.hold_time_remaining = 0;
gettimeofday(&now, NULL);
if (nbr->state == NBR_STA_OPER) {

View File

@ -41,6 +41,10 @@ ldpd_libldp_a_SOURCES = \
ldpd/util.c \
# end
if SNMP
module_LTLIBRARIES += ldpd/ldpd_snmp.la
endif
clippy_scan += \
ldpd/ldp_vty_cmds.c \
# end
@ -59,3 +63,8 @@ noinst_HEADERS += \
ldpd_ldpd_SOURCES = ldpd/ldpd.c
ldpd_ldpd_LDADD = ldpd/libldp.a lib/libfrr.la $(LIBCAP)
ldpd_ldpd_snmp_la_SOURCES = ldpd/ldp_snmp.c
ldpd_ldpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
ldpd_ldpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ldpd_ldpd_snmp_la_LIBADD = lib/libfrrsnmp.la