+// SPDX-License-Identifier: GPL-2.0-or-later
/* SNMP support
* Copyright (C) 2012 Vincent Bernat <bernat@luffy.cx>
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "linklist.h"
#include "lib/version.h"
#include "lib_errors.h"
+#include "hook.h"
+#include "libfrr.h"
#include "xref.h"
XREF_SETUP();
DEFINE_HOOK(agentx_enabled, (), ());
-static int agentx_enabled = 0;
+static bool agentx_enabled = false;
-static struct thread_master *agentx_tm;
-static struct thread *timeout_thr = NULL;
+static struct event_loop *agentx_tm;
+static struct event *timeout_thr = NULL;
static struct list *events = NULL;
static void agentx_events_update(void);
-static void agentx_timeout(struct thread *t)
+static void agentx_timeout(struct event *t)
{
snmp_timeout();
run_alarms();
agentx_events_update();
}
-static void agentx_read(struct thread *t)
+static void agentx_read(struct event *t)
{
fd_set fds;
int flags, new_flags = 0;
int nonblock = false;
- struct listnode *ln = THREAD_ARG(t);
- struct thread **thr = listgetdata(ln);
+ struct listnode *ln = EVENT_ARG(t);
+ struct event **thr = listgetdata(ln);
XFREE(MTYPE_TMP, thr);
list_delete_node(events, ln);
/* fix for non blocking socket */
- flags = fcntl(THREAD_FD(t), F_GETFL, 0);
+ flags = fcntl(EVENT_FD(t), F_GETFL, 0);
if (-1 == flags) {
flog_err(EC_LIB_SYSTEM_CALL, "Failed to get FD settings fcntl: %s(%d)",
strerror(errno), errno);
if (flags & O_NONBLOCK)
nonblock = true;
else
- new_flags = fcntl(THREAD_FD(t), F_SETFL, flags | O_NONBLOCK);
+ new_flags = fcntl(EVENT_FD(t), F_SETFL, flags | O_NONBLOCK);
if (new_flags == -1)
flog_err(EC_LIB_SYSTEM_CALL, "Failed to set snmp fd non blocking: %s(%d)",
strerror(errno), errno);
FD_ZERO(&fds);
- FD_SET(THREAD_FD(t), &fds);
+ FD_SET(EVENT_FD(t), &fds);
snmp_read(&fds);
/* Reset the flag */
if (!nonblock) {
- new_flags = fcntl(THREAD_FD(t), F_SETFL, flags);
+ new_flags = fcntl(EVENT_FD(t), F_SETFL, flags);
if (new_flags == -1)
flog_err(
struct timeval timeout = {.tv_sec = 0, .tv_usec = 0};
fd_set fds;
struct listnode *ln;
- struct thread **thr;
+ struct event **thr;
int fd, thr_fd;
- thread_cancel(&timeout_thr);
+ event_cancel(&timeout_thr);
FD_ZERO(&fds);
snmp_select_info(&maxfd, &fds, &timeout, &block);
if (!block) {
- thread_add_timer_tv(agentx_tm, agentx_timeout, NULL, &timeout,
- &timeout_thr);
+ event_add_timer_tv(agentx_tm, agentx_timeout, NULL, &timeout,
+ &timeout_thr);
}
ln = listhead(events);
thr = ln ? listgetdata(ln) : NULL;
- thr_fd = thr ? THREAD_FD(*thr) : -1;
+ thr_fd = thr ? EVENT_FD(*thr) : -1;
/* "two-pointer" / two-list simultaneous iteration
* ln/thr/thr_fd point to the next existing event listener to hit while
if (thr_fd == fd) {
struct listnode *nextln = listnextnode(ln);
if (!FD_ISSET(fd, &fds)) {
- thread_cancel(thr);
+ event_cancel(thr);
XFREE(MTYPE_TMP, thr);
list_delete_node(events, ln);
}
ln = nextln;
thr = ln ? listgetdata(ln) : NULL;
- thr_fd = thr ? THREAD_FD(*thr) : -1;
+ thr_fd = thr ? EVENT_FD(*thr) : -1;
}
/* need listener, but haven't hit one where it would be */
else if (FD_ISSET(fd, &fds)) {
struct listnode *newln;
- thr = XCALLOC(MTYPE_TMP, sizeof(struct thread *));
+ thr = XCALLOC(MTYPE_TMP, sizeof(struct event *));
newln = listnode_add_before(events, ln, thr);
- thread_add_read(agentx_tm, agentx_read, newln, fd, thr);
+ event_add_read(agentx_tm, agentx_read, newln, fd, thr);
}
}
while (ln) {
struct listnode *nextln = listnextnode(ln);
thr = listgetdata(ln);
- thread_cancel(thr);
+ event_cancel(thr);
XFREE(MTYPE_TMP, thr);
list_delete_node(events, ln);
ln = nextln;
init_snmp(FRR_SMUX_NAME);
events = list_new();
agentx_events_update();
- agentx_enabled = 1;
+ agentx_enabled = true;
hook_call(agentx_enabled);
}
return CMD_WARNING_CONFIG_FAILED;
}
-int smux_enabled(void)
+static int smux_disable(void)
+{
+ agentx_enabled = false;
+
+ return 0;
+}
+
+bool smux_enabled(void)
{
return agentx_enabled;
}
-void smux_init(struct thread_master *tm)
+void smux_init(struct event_loop *tm)
{
agentx_tm = tm;
install_node(&agentx_node);
install_element(CONFIG_NODE, &agentx_enable_cmd);
install_element(CONFIG_NODE, &no_agentx_cmd);
+
+ hook_register(frr_early_fini, smux_disable);
}
void smux_agentx_enable(void)
init_snmp(FRR_SMUX_NAME);
events = list_new();
agentx_events_update();
- agentx_enabled = 1;
+ agentx_enabled = true;
}
}