am__v_PROTOC_C_0 = @echo " PROTOC_C" $@;
am__v_PROTOC_C_1 =
-.proto.pb-c.c:
+%.pb-c.c %.pb-c.h : %.proto
$(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir) --c_out=$(top_builddir) $^
$(AM_V_GEN)$(SED) -i -e '1i\
#include "config.h"' $@
-.pb-c.c.pb-c.h:
- @echo " GEN " $@
-
include doc/subdir.am
include doc/user/subdir.am
include doc/manpages/subdir.am
#include "getopt.h"
#include "if.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "privs.h"
#include "sigevent.h"
#include "lib/version.h"
static void babel_save_state_file(void);
-struct thread_master *master; /* quagga's threads handler */
+struct event_loop *master; /* quagga's threads handler */
struct timeval babel_now; /* current time */
unsigned char myid[8]; /* unique id (mac address of an interface) */
#include "vty.h"
extern struct timeval babel_now; /* current time */
-extern struct thread_master *master; /* quagga's threads handler */
+extern struct event_loop *master; /* quagga's threads handler */
extern int debug;
extern int resend_delay;
DEFINE_MGROUP(BABELD, "babeld");
DEFINE_MTYPE_STATIC(BABELD, BABEL, "Babel Structure");
-static void babel_init_routing_process(struct thread *thread);
+static void babel_init_routing_process(struct event *thread);
static void babel_get_myid(void);
static void babel_initial_noise(void);
-static void babel_read_protocol(struct thread *thread);
-static void babel_main_loop(struct thread *thread);
+static void babel_read_protocol(struct event *thread);
+static void babel_main_loop(struct event *thread);
static void babel_set_timer(struct timeval *timeout);
static void babel_fill_with_next_timeout(struct timeval *tv);
static void
}
/* Threads. */
- thread_add_read(master, babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
+ event_add_read(master, babel_read_protocol, NULL, protocol_socket,
+ &babel_routing_process->t_read);
/* wait a little: zebra will announce interfaces, addresses, routes... */
- thread_add_timer_msec(master, babel_init_routing_process, NULL, 200L, &babel_routing_process->t_update);
+ event_add_timer_msec(master, babel_init_routing_process, NULL, 200L,
+ &babel_routing_process->t_update);
/* Distribute list install. */
babel_routing_process->distribute_ctx = distribute_list_ctx_create (vrf_lookup_by_id(VRF_DEFAULT));
}
/* thread reading entries form others babel daemons */
-static void babel_read_protocol(struct thread *thread)
+static void babel_read_protocol(struct event *thread)
{
int rc;
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
}
/* re-add thread */
- thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
+ event_add_read(master, &babel_read_protocol, NULL, protocol_socket,
+ &babel_routing_process->t_read);
}
/* Zebra will give some information, especially about interfaces. This function
must be call with a litte timeout wich may give zebra the time to do his job,
making these inits have sense. */
-static void babel_init_routing_process(struct thread *thread)
+static void babel_init_routing_process(struct event *thread)
{
myseqno = (frr_weak_random() & 0xFFFF);
babel_get_myid();
babel_interface_close_all();
/* cancel events */
- thread_cancel(&babel_routing_process->t_read);
- thread_cancel(&babel_routing_process->t_update);
+ event_cancel(&babel_routing_process->t_read);
+ event_cancel(&babel_routing_process->t_update);
distribute_list_delete(&babel_routing_process->distribute_ctx);
XFREE(MTYPE_BABEL, babel_routing_process);
}
/* Function used with timeout. */
-static void babel_main_loop(struct thread *thread)
+static void babel_main_loop(struct event *thread)
{
struct timeval tv;
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
babel_set_timer(struct timeval *timeout)
{
long msecs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
- thread_cancel(&(babel_routing_process->t_update));
- thread_add_timer_msec(master, babel_main_loop, NULL, msecs, &babel_routing_process->t_update);
+ event_cancel(&(babel_routing_process->t_update));
+ event_add_timer_msec(master, babel_main_loop, NULL, msecs,
+ &babel_routing_process->t_update);
}
void
struct babel
{
/* Babel threads. */
- struct thread *t_read; /* on Babel protocol's socket */
- struct thread *t_update; /* timers */
+ struct event *t_read; /* on Babel protocol's socket */
+ struct event *t_update; /* timers */
/* distribute_ctx */
struct distribute_ctx *distribute_ctx;
};
#include "command.h"
#include "vty.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "nexthop.h"
#include "util.h"
return bfd_key_lookup(key);
}
-void bfd_xmt_cb(struct thread *t)
+void bfd_xmt_cb(struct event *t)
{
- struct bfd_session *bs = THREAD_ARG(t);
+ struct bfd_session *bs = EVENT_ARG(t);
ptm_bfd_xmt_TO(bs, 0);
}
-void bfd_echo_xmt_cb(struct thread *t)
+void bfd_echo_xmt_cb(struct event *t)
{
- struct bfd_session *bs = THREAD_ARG(t);
+ struct bfd_session *bs = EVENT_ARG(t);
if (bs->echo_xmt_TO > 0)
ptm_bfd_echo_xmt_TO(bs);
}
/* Was ptm_bfd_detect_TO() */
-void bfd_recvtimer_cb(struct thread *t)
+void bfd_recvtimer_cb(struct event *t)
{
- struct bfd_session *bs = THREAD_ARG(t);
+ struct bfd_session *bs = EVENT_ARG(t);
switch (bs->ses_state) {
case PTM_BFD_INIT:
}
/* Was ptm_bfd_echo_detect_TO() */
-void bfd_echo_recvtimer_cb(struct thread *t)
+void bfd_echo_recvtimer_cb(struct event *t)
{
- struct bfd_session *bs = THREAD_ARG(t);
+ struct bfd_session *bs = EVENT_ARG(t);
switch (bs->ses_state) {
case PTM_BFD_INIT:
bvrf->bg_echov6 = bp_echov6_socket(vrf);
if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
- &bvrf->bg_ev[0]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
+ &bvrf->bg_ev[0]);
if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
- &bvrf->bg_ev[1]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
+ &bvrf->bg_ev[1]);
if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
- &bvrf->bg_ev[2]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
+ &bvrf->bg_ev[2]);
if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
- &bvrf->bg_ev[3]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
+ &bvrf->bg_ev[3]);
if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
- &bvrf->bg_ev[4]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
+ &bvrf->bg_ev[4]);
if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
- &bvrf->bg_ev[5]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
+ &bvrf->bg_ev[5]);
if (vrf->vrf_id != VRF_DEFAULT) {
bfdd_zclient_register(vrf->vrf_id);
zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
/* Disable read/write poll triggering. */
- THREAD_OFF(bvrf->bg_ev[0]);
- THREAD_OFF(bvrf->bg_ev[1]);
- THREAD_OFF(bvrf->bg_ev[2]);
- THREAD_OFF(bvrf->bg_ev[3]);
- THREAD_OFF(bvrf->bg_ev[4]);
- THREAD_OFF(bvrf->bg_ev[5]);
+ EVENT_OFF(bvrf->bg_ev[0]);
+ EVENT_OFF(bvrf->bg_ev[1]);
+ EVENT_OFF(bvrf->bg_ev[2]);
+ EVENT_OFF(bvrf->bg_ev[3]);
+ EVENT_OFF(bvrf->bg_ev[4]);
+ EVENT_OFF(bvrf->bg_ev[5]);
/* Close all descriptors. */
socket_close(&bvrf->bg_echo);
struct bfd_config_timers timers;
struct bfd_timers cur_timers;
uint64_t detect_TO;
- struct thread *echo_recvtimer_ev;
- struct thread *recvtimer_ev;
+ struct event *echo_recvtimer_ev;
+ struct event *recvtimer_ev;
uint64_t xmt_TO;
uint64_t echo_xmt_TO;
- struct thread *xmttimer_ev;
- struct thread *echo_xmttimer_ev;
+ struct event *xmttimer_ev;
+ struct event *echo_xmttimer_ev;
uint64_t echo_detect_TO;
/* software object state */
TAILQ_ENTRY(bfd_control_socket) bcs_entry;
int bcs_sd;
- struct thread *bcs_ev;
- struct thread *bcs_outev;
+ struct event *bcs_ev;
+ struct event *bcs_outev;
struct bcqueue bcs_bcqueue;
/* Notification data */
void control_shutdown(void);
int control_notify(struct bfd_session *bs, uint8_t notify_state);
int control_notify_config(const char *op, struct bfd_session *bs);
-void control_accept(struct thread *t);
+void control_accept(struct event *t);
/*
int bg_echov6;
struct vrf *vrf;
- struct thread *bg_ev[6];
+ struct event *bg_ev[6];
};
/* Forward declaration of data plane context struct. */
struct bfd_global {
int bg_csock;
- struct thread *bg_csockev;
+ struct event *bg_csockev;
struct bcslist bg_bcslist;
struct pllist bg_pllist;
/* Distributed BFD items. */
bool bg_use_dplane;
int bg_dplane_sock;
- struct thread *bg_dplane_sockev;
+ struct event *bg_dplane_sockev;
struct dplane_queue bg_dplaneq;
/* Debug options. */
void ptm_bfd_echo_snd(struct bfd_session *bfd);
void ptm_bfd_echo_fp_snd(struct bfd_session *bfd);
-void bfd_recv_cb(struct thread *t);
+void bfd_recv_cb(struct event *t);
/*
*
* Contains the code related with event loop.
*/
-typedef void (*bfd_ev_cb)(struct thread *t);
+typedef void (*bfd_ev_cb)(struct event *t);
void bfd_recvtimer_update(struct bfd_session *bs);
void bfd_echo_recvtimer_update(struct bfd_session *bs);
unsigned long bfd_get_session_count(void);
/* Export callback functions for `event.c`. */
-extern struct thread_master *master;
+extern struct event_loop *master;
-void bfd_recvtimer_cb(struct thread *t);
-void bfd_echo_recvtimer_cb(struct thread *t);
-void bfd_xmt_cb(struct thread *t);
-void bfd_echo_xmt_cb(struct thread *t);
+void bfd_recvtimer_cb(struct event *t);
+void bfd_echo_recvtimer_cb(struct event *t);
+void bfd_xmt_cb(struct event *t);
+void bfd_echo_xmt_cb(struct event *t);
extern struct in6_addr zero_addr;
static void bfd_sd_reschedule(struct bfd_vrf_global *bvrf, int sd)
{
if (sd == bvrf->bg_shop) {
- THREAD_OFF(bvrf->bg_ev[0]);
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
- &bvrf->bg_ev[0]);
+ EVENT_OFF(bvrf->bg_ev[0]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
+ &bvrf->bg_ev[0]);
} else if (sd == bvrf->bg_mhop) {
- THREAD_OFF(bvrf->bg_ev[1]);
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
- &bvrf->bg_ev[1]);
+ EVENT_OFF(bvrf->bg_ev[1]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
+ &bvrf->bg_ev[1]);
} else if (sd == bvrf->bg_shop6) {
- THREAD_OFF(bvrf->bg_ev[2]);
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
- &bvrf->bg_ev[2]);
+ EVENT_OFF(bvrf->bg_ev[2]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
+ &bvrf->bg_ev[2]);
} else if (sd == bvrf->bg_mhop6) {
- THREAD_OFF(bvrf->bg_ev[3]);
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
- &bvrf->bg_ev[3]);
+ EVENT_OFF(bvrf->bg_ev[3]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
+ &bvrf->bg_ev[3]);
} else if (sd == bvrf->bg_echo) {
- THREAD_OFF(bvrf->bg_ev[4]);
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
- &bvrf->bg_ev[4]);
+ EVENT_OFF(bvrf->bg_ev[4]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
+ &bvrf->bg_ev[4]);
} else if (sd == bvrf->bg_echov6) {
- THREAD_OFF(bvrf->bg_ev[5]);
- thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
- &bvrf->bg_ev[5]);
+ EVENT_OFF(bvrf->bg_ev[5]);
+ event_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
+ &bvrf->bg_ev[5]);
}
}
mhop ? "yes" : "no", peerstr, localstr, portstr, vrfstr);
}
-void bfd_recv_cb(struct thread *t)
+void bfd_recv_cb(struct event *t)
{
- int sd = THREAD_FD(t);
+ int sd = EVENT_FD(t);
struct bfd_session *bfd;
struct bfd_pkt *cp;
bool is_mhop;
struct sockaddr_any local, peer;
uint8_t msgbuf[1516];
struct interface *ifp = NULL;
- struct bfd_vrf_global *bvrf = THREAD_ARG(t);
+ struct bfd_vrf_global *bvrf = EVENT_ARG(t);
/* Schedule next read. */
bfd_sd_reschedule(bvrf, sd);
DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data");
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/* BFDd privileges */
static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_SYS_ADMIN, ZCAP_NET_RAW};
/* Initialize zebra connection. */
bfdd_zclient_init(&bglobal.bfdd_privs);
- thread_add_read(master, control_accept, NULL, bglobal.bg_csock,
- &bglobal.bg_csockev);
+ event_add_read(master, control_accept, NULL, bglobal.bg_csock,
+ &bglobal.bg_csockev);
/* Install commands. */
bfdd_vty_init();
struct bfd_control_socket *control_new(int sd);
static void control_free(struct bfd_control_socket *bcs);
static void control_reset_buf(struct bfd_control_buffer *bcb);
-static void control_read(struct thread *t);
-static void control_write(struct thread *t);
+static void control_read(struct event *t);
+static void control_write(struct event *t);
static void control_handle_request_add(struct bfd_control_socket *bcs,
struct bfd_control_msg *bcm);
{
struct bfd_control_socket *bcs;
- thread_cancel(&bglobal.bg_csockev);
+ event_cancel(&bglobal.bg_csockev);
socket_close(&bglobal.bg_csock);
}
}
-void control_accept(struct thread *t)
+void control_accept(struct event *t)
{
- int csock, sd = THREAD_FD(t);
+ int csock, sd = EVENT_FD(t);
csock = accept(sd, NULL, 0);
if (csock == -1) {
control_new(csock);
- thread_add_read(master, control_accept, NULL, sd, &bglobal.bg_csockev);
+ event_add_read(master, control_accept, NULL, sd, &bglobal.bg_csockev);
}
bcs->bcs_notify = 0;
bcs->bcs_sd = sd;
- thread_add_read(master, control_read, bcs, sd, &bcs->bcs_ev);
+ event_add_read(master, control_read, bcs, sd, &bcs->bcs_ev);
TAILQ_INIT(&bcs->bcs_bcqueue);
TAILQ_INIT(&bcs->bcs_bnplist);
struct bfd_control_queue *bcq;
struct bfd_notify_peer *bnp;
- thread_cancel(&(bcs->bcs_ev));
- thread_cancel(&(bcs->bcs_outev));
+ event_cancel(&(bcs->bcs_ev));
+ event_cancel(&(bcs->bcs_outev));
close(bcs->bcs_sd);
bcs->bcs_bout = &bcq->bcq_bcb;
bcs->bcs_outev = NULL;
- thread_add_write(master, control_write, bcs, bcs->bcs_sd,
- &bcs->bcs_outev);
+ event_add_write(master, control_write, bcs, bcs->bcs_sd,
+ &bcs->bcs_outev);
return 1;
empty_list:
- thread_cancel(&(bcs->bcs_outev));
+ event_cancel(&(bcs->bcs_outev));
bcs->bcs_bout = NULL;
return 0;
}
bcs->bcs_bout = bcb;
/* New messages, active write events. */
- thread_add_write(master, control_write, bcs, bcs->bcs_sd,
- &bcs->bcs_outev);
+ event_add_write(master, control_write, bcs, bcs->bcs_sd,
+ &bcs->bcs_outev);
}
return 0;
bcb->bcb_left = 0;
}
-static void control_read(struct thread *t)
+static void control_read(struct event *t)
{
- struct bfd_control_socket *bcs = THREAD_ARG(t);
+ struct bfd_control_socket *bcs = EVENT_ARG(t);
struct bfd_control_buffer *bcb = &bcs->bcs_bin;
int sd = bcs->bcs_sd;
struct bfd_control_msg bcm;
schedule_next_read:
bcs->bcs_ev = NULL;
- thread_add_read(master, control_read, bcs, sd, &bcs->bcs_ev);
+ event_add_read(master, control_read, bcs, sd, &bcs->bcs_ev);
}
-static void control_write(struct thread *t)
+static void control_write(struct event *t)
{
- struct bfd_control_socket *bcs = THREAD_ARG(t);
+ struct bfd_control_socket *bcs = EVENT_ARG(t);
struct bfd_control_buffer *bcb = bcs->bcs_bout;
int sd = bcs->bcs_sd;
ssize_t bwrite;
if (bwrite < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
bcs->bcs_outev = NULL;
- thread_add_write(master, control_write, bcs,
- bcs->bcs_sd, &bcs->bcs_outev);
+ event_add_write(master, control_write, bcs, bcs->bcs_sd,
+ &bcs->bcs_outev);
return;
}
bcb->bcb_left -= bwrite;
if (bcb->bcb_left > 0) {
bcs->bcs_outev = NULL;
- thread_add_write(master, control_write, bcs, bcs->bcs_sd,
- &bcs->bcs_outev);
+ event_add_write(master, control_write, bcs, bcs->bcs_sd,
+ &bcs->bcs_outev);
return;
}
#include "lib/network.h"
#include "lib/printfrr.h"
#include "lib/stream.h"
-#include "lib/thread.h"
+#include "lib/frrevent.h"
#include "bfd.h"
#include "bfddp_packet.h"
/** Output buffer data. */
struct stream *outbuf;
/** Input event data. */
- struct thread *inbufev;
+ struct event *inbufev;
/** Output event data. */
- struct thread *outbufev;
+ struct event *outbufev;
/** Connection event. */
- struct thread *connectev;
+ struct event *connectev;
/** Amount of bytes read. */
uint64_t in_bytes;
*/
typedef void (*bfd_dplane_expect_cb)(struct bfddp_message *msg, void *arg);
-static void bfd_dplane_client_connect(struct thread *t);
+static void bfd_dplane_client_connect(struct event *t);
static bool bfd_dplane_client_connecting(struct bfd_dplane_ctx *bdc);
static void bfd_dplane_ctx_free(struct bfd_dplane_ctx *bdc);
static int _bfd_dplane_add_session(struct bfd_dplane_ctx *bdc,
stream_pulldown(bdc->outbuf);
/* Disable write ready events. */
- THREAD_OFF(bdc->outbufev);
+ EVENT_OFF(bdc->outbufev);
return total;
}
-static void bfd_dplane_write(struct thread *t)
+static void bfd_dplane_write(struct event *t)
{
- struct bfd_dplane_ctx *bdc = THREAD_ARG(t);
+ struct bfd_dplane_ctx *bdc = EVENT_ARG(t);
/* Handle connection stage. */
if (bdc->connecting && bfd_dplane_client_connecting(bdc))
/* Schedule if it is not yet. */
if (bdc->outbufev == NULL)
- thread_add_write(master, bfd_dplane_write, bdc, bdc->sock,
- &bdc->outbufev);
+ event_add_write(master, bfd_dplane_write, bdc, bdc->sock,
+ &bdc->outbufev);
return 0;
}
return 0;
}
-static void bfd_dplane_read(struct thread *t)
+static void bfd_dplane_read(struct event *t)
{
- struct bfd_dplane_ctx *bdc = THREAD_ARG(t);
+ struct bfd_dplane_ctx *bdc = EVENT_ARG(t);
int rv;
rv = bfd_dplane_expect(bdc, 0, bfd_dplane_handle_message, NULL);
return;
stream_pulldown(bdc->inbuf);
- thread_add_read(master, bfd_dplane_read, bdc, bdc->sock, &bdc->inbufev);
+ event_add_read(master, bfd_dplane_read, bdc, bdc->sock, &bdc->inbufev);
}
static void _bfd_session_register_dplane(struct hash_bucket *hb, void *arg)
if (sock == -1)
return bdc;
- thread_add_read(master, bfd_dplane_read, bdc, sock, &bdc->inbufev);
+ event_add_read(master, bfd_dplane_read, bdc, sock, &bdc->inbufev);
/* Register all unattached sessions. */
bfd_key_iterate(_bfd_session_register_dplane, bdc);
/* Client mode has special treatment. */
if (bdc->client) {
/* Disable connection event if any. */
- THREAD_OFF(bdc->connectev);
+ EVENT_OFF(bdc->connectev);
/* Normal treatment on shutdown. */
if (bglobal.bg_shutdown)
/* Attempt reconnection. */
socket_close(&bdc->sock);
- THREAD_OFF(bdc->inbufev);
- THREAD_OFF(bdc->outbufev);
- thread_add_timer(master, bfd_dplane_client_connect, bdc, 3,
- &bdc->connectev);
+ EVENT_OFF(bdc->inbufev);
+ EVENT_OFF(bdc->outbufev);
+ event_add_timer(master, bfd_dplane_client_connect, bdc, 3,
+ &bdc->connectev);
return;
}
socket_close(&bdc->sock);
stream_free(bdc->inbuf);
stream_free(bdc->outbuf);
- THREAD_OFF(bdc->inbufev);
- THREAD_OFF(bdc->outbufev);
+ EVENT_OFF(bdc->inbufev);
+ EVENT_OFF(bdc->outbufev);
XFREE(MTYPE_BFDD_DPLANE_CTX, bdc);
}
/*
* Data plane listening socket.
*/
-static void bfd_dplane_accept(struct thread *t)
+static void bfd_dplane_accept(struct event *t)
{
- struct bfd_global *bg = THREAD_ARG(t);
+ struct bfd_global *bg = EVENT_ARG(t);
struct bfd_dplane_ctx *bdc;
int sock;
zlog_debug("%s: new data plane client connected", __func__);
reschedule_and_return:
- thread_add_read(master, bfd_dplane_accept, bg, bg->bg_dplane_sock,
- &bglobal.bg_dplane_sockev);
+ event_add_read(master, bfd_dplane_accept, bg, bg->bg_dplane_sock,
+ &bglobal.bg_dplane_sockev);
}
/*
stream_reset(bdc->outbuf);
/* Ask for read notifications. */
- thread_add_read(master, bfd_dplane_read, bdc, bdc->sock, &bdc->inbufev);
+ event_add_read(master, bfd_dplane_read, bdc, bdc->sock, &bdc->inbufev);
/* Remove all sessions then register again to send them all. */
bfd_key_iterate(_bfd_session_unregister_dplane, bdc);
}
}
-static void bfd_dplane_client_connect(struct thread *t)
+static void bfd_dplane_client_connect(struct event *t)
{
- struct bfd_dplane_ctx *bdc = THREAD_ARG(t);
+ struct bfd_dplane_ctx *bdc = EVENT_ARG(t);
int rv, sock;
socklen_t rvlen = sizeof(rv);
/* If we are not connected yet, ask for write notifications. */
bdc->connecting = true;
- thread_add_write(master, bfd_dplane_write, bdc, bdc->sock,
- &bdc->outbufev);
+ event_add_write(master, bfd_dplane_write, bdc, bdc->sock,
+ &bdc->outbufev);
} else {
if (bglobal.debug_dplane)
zlog_debug("%s: server connection: %d", __func__, sock);
}
reschedule_connect:
- THREAD_OFF(bdc->inbufev);
- THREAD_OFF(bdc->outbufev);
+ EVENT_OFF(bdc->inbufev);
+ EVENT_OFF(bdc->outbufev);
socket_close(&sock);
- thread_add_timer(master, bfd_dplane_client_connect, bdc, 3,
- &bdc->connectev);
+ event_add_timer(master, bfd_dplane_client_connect, bdc, 3,
+ &bdc->connectev);
}
static void bfd_dplane_client_init(const struct sockaddr *sa, socklen_t salen)
bdc->client = true;
- thread_add_timer(master, bfd_dplane_client_connect, bdc, 0,
- &bdc->connectev);
+ event_add_timer(master, bfd_dplane_client_connect, bdc, 0,
+ &bdc->connectev);
/* Insert into data plane lists. */
TAILQ_INSERT_TAIL(&bglobal.bg_dplaneq, bdc, entry);
bfd_dplane_ctx_free(bdc);
/* Cancel accept thread and close socket. */
- THREAD_OFF(bglobal.bg_dplane_sockev);
+ EVENT_OFF(bglobal.bg_dplane_sockev);
close(bglobal.bg_dplane_sock);
return 0;
}
bglobal.bg_dplane_sock = sock;
- thread_add_read(master, bfd_dplane_accept, &bglobal, sock,
- &bglobal.bg_dplane_sockev);
+ event_add_read(master, bfd_dplane_accept, &bglobal, sock,
+ &bglobal.bg_dplane_sockev);
}
int bfd_dplane_add_session(struct bfd_session *bs)
tv_normalize(&tv);
- thread_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv,
- &bs->recvtimer_ev);
+ event_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv,
+ &bs->recvtimer_ev);
}
void bfd_echo_recvtimer_update(struct bfd_session *bs)
tv_normalize(&tv);
- thread_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv,
- &bs->echo_recvtimer_ev);
+ event_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv,
+ &bs->echo_recvtimer_ev);
}
void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
tv_normalize(&tv);
- thread_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev);
+ event_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev);
}
void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
tv_normalize(&tv);
- thread_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv,
- &bs->echo_xmttimer_ev);
+ event_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv,
+ &bs->echo_xmttimer_ev);
}
void bfd_recvtimer_delete(struct bfd_session *bs)
{
- THREAD_OFF(bs->recvtimer_ev);
+ EVENT_OFF(bs->recvtimer_ev);
}
void bfd_echo_recvtimer_delete(struct bfd_session *bs)
{
- THREAD_OFF(bs->echo_recvtimer_ev);
+ EVENT_OFF(bs->echo_recvtimer_ev);
}
void bfd_xmttimer_delete(struct bfd_session *bs)
{
- THREAD_OFF(bs->xmttimer_ev);
+ EVENT_OFF(bs->xmttimer_ev);
}
void bfd_echo_xmttimer_delete(struct bfd_session *bs)
{
- THREAD_OFF(bs->echo_xmttimer_ev);
+ EVENT_OFF(bs->echo_xmttimer_ev);
}
#include "memory.h"
#include "prefix.h"
#include "hash.h"
-#include "thread.h"
+#include "frrevent.h"
#include "queue.h"
#include "filter.h"
void aspath_finish(void)
{
- hash_clean(ashash, (void (*)(void *))aspath_free);
- hash_free(ashash);
- ashash = NULL;
+ hash_clean_and_free(&ashash, (void (*)(void *))aspath_free);
if (snmp_stream)
stream_free(snmp_stream);
static void cluster_finish(void)
{
- hash_clean(cluster_hash, (void (*)(void *))cluster_free);
- hash_free(cluster_hash);
- cluster_hash = NULL;
+ hash_clean_and_free(&cluster_hash, (void (*)(void *))cluster_free);
}
static struct hash *encap_hash = NULL;
static void encap_finish(void)
{
- hash_clean(encap_hash, (void (*)(void *))encap_free);
- hash_free(encap_hash);
- encap_hash = NULL;
+ hash_clean_and_free(&encap_hash, (void (*)(void *))encap_free);
#ifdef ENABLE_BGP_VNC
- hash_clean(vnc_hash, (void (*)(void *))encap_free);
- hash_free(vnc_hash);
- vnc_hash = NULL;
+ hash_clean_and_free(&vnc_hash, (void (*)(void *))encap_free);
#endif
}
static void srv6_finish(void)
{
- hash_clean(srv6_l3vpn_hash, (void (*)(void *))srv6_l3vpn_free);
- hash_free(srv6_l3vpn_hash);
- srv6_l3vpn_hash = NULL;
- hash_clean(srv6_vpn_hash, (void (*)(void *))srv6_vpn_free);
- hash_free(srv6_vpn_hash);
- srv6_vpn_hash = NULL;
+ hash_clean_and_free(&srv6_l3vpn_hash,
+ (void (*)(void *))srv6_l3vpn_free);
+ hash_clean_and_free(&srv6_vpn_hash, (void (*)(void *))srv6_vpn_free);
}
static unsigned int transit_hash_key_make(const void *p)
static void transit_finish(void)
{
- hash_clean(transit_hash, (void (*)(void *))transit_free);
- hash_free(transit_hash);
- transit_hash = NULL;
+ hash_clean_and_free(&transit_hash, (void (*)(void *))transit_free);
}
/* Attribute hash routines. */
static void attrhash_finish(void)
{
- hash_clean(attrhash, attr_vfree);
- hash_free(attrhash);
- attrhash = NULL;
+ hash_clean_and_free(&attrhash, attr_vfree);
}
static void attr_show_all_iterator(struct hash_bucket *bucket, struct vty *vty)
int srgb_count;
uint8_t sid_type, sid_flags;
+ /*
+ * Check that we actually have at least as much data as
+ * specified by the length field
+ */
+ if (STREAM_READABLE(peer->curr) < length) {
+ flog_err(
+ EC_BGP_ATTR_LEN,
+ "Prefix SID specifies length %hu, but only %zu bytes remain",
+ length, STREAM_READABLE(peer->curr));
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
if (type == BGP_PREFIX_SID_LABEL_INDEX) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
+ if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
flog_err(EC_BGP_ATTR_LEN,
"Prefix SID label index length is %hu instead of %u",
length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
/* Store label index; subsequently, we'll check on
* address-family */
attr->label_index = label_index;
- }
-
- /* Placeholder code for the IPv6 SID type */
- else if (type == BGP_PREFIX_SID_IPV6) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_IPV6_LENGTH) {
+ } else if (type == BGP_PREFIX_SID_IPV6) {
+ if (length != BGP_PREFIX_SID_IPV6_LENGTH) {
flog_err(EC_BGP_ATTR_LEN,
"Prefix SID IPv6 length is %hu instead of %u",
length, BGP_PREFIX_SID_IPV6_LENGTH);
stream_getw(peer->curr);
stream_get(&ipv6_sid, peer->curr, 16);
- }
-
- /* Placeholder code for the Originator SRGB type */
- else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
+ } else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
/*
* ietf-idr-bgp-prefix-sid-05:
* Length is the total length of the value portion of the
args->total);
}
- /*
- * Check that we actually have at least as much data as
- * specified by the length field
- */
- if (STREAM_READABLE(peer->curr) < length) {
- flog_err(EC_BGP_ATTR_LEN,
- "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
- length, STREAM_READABLE(peer->curr));
- return bgp_attr_malformed(
- args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- args->total);
- }
-
/*
* Check that the portion of the TLV containing the sequence of
* SRGBs corresponds to a multiple of the SRGB size; to get
stream_get(&srgb_base, peer->curr, 3);
stream_get(&srgb_range, peer->curr, 3);
}
- }
-
- /* Placeholder code for the VPN-SID Service type */
- else if (type == BGP_PREFIX_SID_VPN_SID) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
+ } else if (type == BGP_PREFIX_SID_VPN_SID) {
+ if (length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
flog_err(EC_BGP_ATTR_LEN,
"Prefix SID VPN SID length is %hu instead of %u",
length, BGP_PREFIX_SID_VPN_SID_LENGTH);
attr->srv6_vpn->sid_flags = sid_flags;
sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
- }
-
- /* Placeholder code for the SRv6 L3 Service type */
- else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
- if (STREAM_READABLE(peer->curr) < length) {
+ } else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
+ if (STREAM_READABLE(peer->curr) < 1) {
flog_err(
EC_BGP_ATTR_LEN,
- "Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain",
- length, STREAM_READABLE(peer->curr));
- return bgp_attr_malformed(args,
- BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- args->total);
+ "Prefix SID SRV6 L3 Service not enough data left, it must be at least 1 byte");
+ return bgp_attr_malformed(
+ args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
}
-
/* ignore reserved */
stream_getc(peer->curr);
return bgp_attr_srv6_service(args);
}
-
/* Placeholder code for Unsupported TLV */
else {
-
- if (STREAM_READABLE(peer->curr) < length) {
- flog_err(
- EC_BGP_ATTR_LEN,
- "Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
- length, STREAM_READABLE(peer->curr));
- return bgp_attr_malformed(
- args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- args->total);
- }
-
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug(
"%s attr Prefix-SID sub-type=%u is not supported, skipped",
#include "linklist.h"
#include "memory.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "stream.h"
#include "vrf.h"
}
peer->last_reset = PEER_DOWN_BFD_DOWN;
- /* draft-ietf-idr-bfd-subcode */
+ /* rfc9384 */
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_BFD_DOWN);
}
#endif /* HAVE_BFDD */
-void bgp_bfd_init(struct thread_master *tm)
+void bgp_bfd_init(struct event_loop *tm)
{
/* Initialize BFD client functions */
bfd_protocol_integration_init(zclient, tm);
((((peer)->sort == BGP_PEER_IBGP) && !(peer)->shared_network) \
|| is_ebgp_multihop_configured((peer)))
-extern void bgp_bfd_init(struct thread_master *tm);
+extern void bgp_bfd_init(struct event_loop *tm);
extern void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
const char *addr);
#include "sockunion.h"
#include "command.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "queue.h"
#include "pullwr.h"
/* Local Port, Remote Port */
if (peer->su_local->sa.sa_family == AF_INET6)
- stream_putw(s, peer->su_local->sin6.sin6_port);
+ stream_putw(s, htons(peer->su_local->sin6.sin6_port));
else if (peer->su_local->sa.sa_family == AF_INET)
- stream_putw(s, peer->su_local->sin.sin_port);
+ stream_putw(s, htons(peer->su_local->sin.sin_port));
if (peer->su_remote->sa.sa_family == AF_INET6)
- stream_putw(s, peer->su_remote->sin6.sin6_port);
+ stream_putw(s, htons(peer->su_remote->sin6.sin6_port));
else if (peer->su_remote->sa.sa_family == AF_INET)
- stream_putw(s, peer->su_remote->sin.sin_port);
+ stream_putw(s, htons(peer->su_remote->sin.sin_port));
static const uint8_t dummy_open[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
(*cnt)++;
}
-static void bmp_stats(struct thread *thread)
+static void bmp_stats(struct event *thread)
{
- struct bmp_targets *bt = THREAD_ARG(thread);
+ struct bmp_targets *bt = EVENT_ARG(thread);
struct stream *s;
struct peer *peer;
struct listnode *node;
struct timeval tv;
if (bt->stat_msec)
- thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
- &bt->t_stats);
+ event_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
+ &bt->t_stats);
gettimeofday(&tv, NULL);
}
/* read from the BMP socket to detect session termination */
-static void bmp_read(struct thread *t)
+static void bmp_read(struct event *t)
{
- struct bmp *bmp = THREAD_ARG(t);
+ struct bmp *bmp = EVENT_ARG(t);
char buf[1024];
ssize_t n;
return;
}
- thread_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read);
+ event_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read);
}
static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock)
bmp->state = BMP_PeerUp;
bmp->pullwr = pullwr_new(bm->master, bmp_sock, bmp, bmp_wrfill,
bmp_wrerr);
- thread_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read);
+ event_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read);
bmp_send_initiation(bmp);
return bmp;
}
/* Accept BMP connection. */
-static void bmp_accept(struct thread *thread)
+static void bmp_accept(struct event *thread)
{
union sockunion su;
- struct bmp_listener *bl = THREAD_ARG(thread);
+ struct bmp_listener *bl = EVENT_ARG(thread);
int bmp_sock;
/* We continue hearing BMP socket. */
- thread_add_read(bm->master, bmp_accept, bl, bl->sock, &bl->t_accept);
+ event_add_read(bm->master, bmp_accept, bl, bl->sock, &bl->t_accept);
memset(&su, 0, sizeof(union sockunion));
struct bmp_queue_entry *bqe;
struct bmp_mirrorq *bmq;
- THREAD_OFF(bmp->t_read);
+ EVENT_OFF(bmp->t_read);
if (bmp->active)
bmp_active_disconnected(bmp->active);
if (!bqe->refcount)
XFREE(MTYPE_BMP_QUEUE, bqe);
- THREAD_OFF(bmp->t_read);
+ EVENT_OFF(bmp->t_read);
pullwr_del(bmp->pullwr);
close(bmp->socket);
}
struct bmp *bmp;
struct bmp_active *ba;
- THREAD_OFF(bt->t_stats);
+ EVENT_OFF(bt->t_stats);
frr_each_safe (bmp_actives, &bt->actives, ba)
bmp_active_put(ba);
goto out_sock;
bl->sock = sock;
- thread_add_read(bm->master, bmp_accept, bl, sock, &bl->t_accept);
+ event_add_read(bm->master, bmp_accept, bl, sock, &bl->t_accept);
return;
out_sock:
close(sock);
static void bmp_listener_stop(struct bmp_listener *bl)
{
- THREAD_OFF(bl->t_accept);
+ EVENT_OFF(bl->t_accept);
if (bl->sock != -1)
close(bl->sock);
static void bmp_active_put(struct bmp_active *ba)
{
- THREAD_OFF(ba->t_timer);
- THREAD_OFF(ba->t_read);
- THREAD_OFF(ba->t_write);
+ EVENT_OFF(ba->t_timer);
+ EVENT_OFF(ba->t_read);
+ EVENT_OFF(ba->t_write);
bmp_actives_del(&ba->targets->actives, ba);
bmp_active_connect(ba);
}
-static void bmp_active_thread(struct thread *t)
+static void bmp_active_thread(struct event *t)
{
- struct bmp_active *ba = THREAD_ARG(t);
+ struct bmp_active *ba = EVENT_ARG(t);
socklen_t slen;
int status, ret;
vrf_id_t vrf_id;
/* all 3 end up here, though only timer or read+write are active
* at a time */
- THREAD_OFF(ba->t_timer);
- THREAD_OFF(ba->t_read);
- THREAD_OFF(ba->t_write);
+ EVENT_OFF(ba->t_timer);
+ EVENT_OFF(ba->t_read);
+ EVENT_OFF(ba->t_write);
ba->last_err = NULL;
static void bmp_active_setup(struct bmp_active *ba)
{
- THREAD_OFF(ba->t_timer);
- THREAD_OFF(ba->t_read);
- THREAD_OFF(ba->t_write);
+ EVENT_OFF(ba->t_timer);
+ EVENT_OFF(ba->t_read);
+ EVENT_OFF(ba->t_write);
if (ba->bmp)
return;
ba->curretry = ba->maxretry;
if (ba->socket == -1)
- thread_add_timer_msec(bm->master, bmp_active_thread, ba,
- ba->curretry, &ba->t_timer);
+ event_add_timer_msec(bm->master, bmp_active_thread, ba,
+ ba->curretry, &ba->t_timer);
else {
- thread_add_read(bm->master, bmp_active_thread, ba, ba->socket,
- &ba->t_read);
- thread_add_write(bm->master, bmp_active_thread, ba, ba->socket,
+ event_add_read(bm->master, bmp_active_thread, ba, ba->socket,
+ &ba->t_read);
+ event_add_write(bm->master, bmp_active_thread, ba, ba->socket,
&ba->t_write);
}
}
{
VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
- THREAD_OFF(bt->t_stats);
+ EVENT_OFF(bt->t_stats);
if (no)
bt->stat_msec = 0;
else if (interval_str)
bt->stat_msec = BMP_STAT_DEFAULT_TIMER;
if (bt->stat_msec)
- thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
- &bt->t_stats);
+ event_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
+ &bt->t_stats);
return CMD_SUCCESS;
}
uptime[0] = '\0';
if (ba->t_timer) {
- long trem = thread_timer_remain_second(
+ long trem = event_timer_remain_second(
ba->t_timer);
peer_uptime(monotime(NULL) - trem,
return 0;
}
-static int bgp_bmp_init(struct thread_master *tm)
+static int bgp_bmp_init(struct event_loop *tm)
{
install_node(&bmp_node);
install_default(BMP_NODE);
int socket;
char remote[SU_ADDRSTRLEN + 6];
- struct thread *t_read;
+ struct event *t_read;
struct pullwr *pullwr;
union sockunion addrs[8];
int socket;
const char *last_err;
- struct thread *t_timer, *t_read, *t_write;
+ struct event *t_timer, *t_read, *t_write;
};
/* config & state for passive / listening sockets */
union sockunion addr;
int port;
- struct thread *t_accept;
+ struct event *t_accept;
int sock;
};
struct bmp_actives_head actives;
- struct thread *t_stats;
+ struct event *t_stats;
struct bmp_session_head sessions;
struct bmp_qhash_head updhash;
void community_finish(void)
{
- hash_clean(comhash, community_hash_free);
- hash_free(comhash);
- comhash = NULL;
+ hash_clean_and_free(&comhash, community_hash_free);
}
static struct community *bgp_aggr_community_lookup(
void bgp_community_alias_finish(void)
{
- hash_clean(bgp_ca_community_hash, bgp_ca_free);
- hash_free(bgp_ca_community_hash);
- hash_clean(bgp_ca_alias_hash, bgp_ca_free);
- hash_free(bgp_ca_alias_hash);
+ hash_clean_and_free(&bgp_ca_community_hash, bgp_ca_free);
+ hash_clean_and_free(&bgp_ca_alias_hash, bgp_ca_free);
}
static void bgp_community_alias_show_iterator(struct hash_bucket *hb,
/* Handler of conditional advertisement timer event.
* Each route in the condition-map is evaluated.
*/
-static void bgp_conditional_adv_timer(struct thread *t)
+static void bgp_conditional_adv_timer(struct event *t)
{
afi_t afi;
safi_t safi;
route_map_result_t ret;
bool advmap_table_changed = false;
- bgp = THREAD_ARG(t);
+ bgp = EVENT_ARG(t);
assert(bgp);
- thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp,
- bgp->condition_check_period, &bgp->t_condition_check);
+ event_add_timer(bm->master, bgp_conditional_adv_timer, bgp,
+ bgp->condition_check_period, &bgp->t_condition_check);
/* loop through each peer and check if we have peers with
* advmap_table_change attribute set, to make sure we send
}
/* Register for conditional routes polling timer */
- if (!thread_is_scheduled(bgp->t_condition_check))
- thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp, 0,
- &bgp->t_condition_check);
+ if (!event_is_scheduled(bgp->t_condition_check))
+ event_add_timer(bm->master, bgp_conditional_adv_timer, bgp, 0,
+ &bgp->t_condition_check);
}
void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi)
}
/* Last filter removed. So cancel conditional routes polling thread. */
- THREAD_OFF(bgp->t_condition_check);
+ EVENT_OFF(bgp->t_condition_check);
}
static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi,
#include "memory.h"
#include "command.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "queue.h"
#include "filter.h"
/* Handler of reuse timer event. Each route in the current reuse-list
is evaluated. RFC2439 Section 4.8.7. */
-static void bgp_reuse_timer(struct thread *t)
+static void bgp_reuse_timer(struct event *t)
{
struct bgp_damp_info *bdi;
struct bgp_damp_info *next;
time_t t_now, t_diff;
- struct bgp_damp_config *bdc = THREAD_ARG(t);
+ struct bgp_damp_config *bdc = EVENT_ARG(t);
bdc->t_reuse = NULL;
- thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
- &bdc->t_reuse);
+ event_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
+ &bdc->t_reuse);
t_now = monotime(NULL);
bgp_damp_parameter_set(half, reuse, suppress, max, bdc);
/* Register reuse timer. */
- thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
- &bdc->t_reuse);
+ event_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE,
+ &bdc->t_reuse);
return 0;
}
return 0;
/* Cancel reuse event. */
- THREAD_OFF(bdc->t_reuse);
+ EVENT_OFF(bdc->t_reuse);
/* Clean BGP dampening information. */
bgp_damp_info_clean(afi, safi);
struct bgp_damp_info *no_reuse_list;
/* Reuse timer thread per-set base. */
- struct thread *t_reuse;
+ struct event *t_reuse;
afi_t afi;
safi_t safi;
#include "sockunion.h"
#include "command.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "queue.h"
#include "memory.h"
char *interval_str;
- struct thread *t_interval;
+ struct event *t_interval;
};
static int bgp_dump_unset(struct bgp_dump *bgp_dump);
-static void bgp_dump_interval_func(struct thread *);
+static void bgp_dump_interval_func(struct event *);
/* BGP packet dump output buffer. */
struct stream *bgp_dump_obuf;
interval = interval
- secs_into_day % interval; /* always > 0 */
}
- thread_add_timer(bm->master, bgp_dump_interval_func, bgp_dump,
- interval, &bgp_dump->t_interval);
+ event_add_timer(bm->master, bgp_dump_interval_func, bgp_dump,
+ interval, &bgp_dump->t_interval);
} else {
/* One-off dump: execute immediately, don't affect any scheduled
* dumps */
- thread_add_event(bm->master, bgp_dump_interval_func, bgp_dump,
- 0, &bgp_dump->t_interval);
+ event_add_event(bm->master, bgp_dump_interval_func, bgp_dump, 0,
+ &bgp_dump->t_interval);
}
return 0;
return seq;
}
-static void bgp_dump_interval_func(struct thread *t)
+static void bgp_dump_interval_func(struct event *t)
{
struct bgp_dump *bgp_dump;
- bgp_dump = THREAD_ARG(t);
+ bgp_dump = EVENT_ARG(t);
/* Reschedule dump even if file couldn't be opened this time... */
if (bgp_dump_open_file(bgp_dump) != NULL) {
}
/* Removing interval event. */
- THREAD_OFF(bgp_dump->t_interval);
+ EVENT_OFF(bgp_dump->t_interval);
bgp_dump->interval = 0;
memset(&bgp_dump_routes, 0, sizeof(bgp_dump_routes));
bgp_dump_obuf =
- stream_new((BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE * 2)
- + BGP_DUMP_MSG_HEADER + BGP_DUMP_HEADER_SIZE);
+ stream_new(BGP_MAX_PACKET_SIZE + BGP_MAX_PACKET_SIZE_OVERFLOW);
install_node(&bgp_dump_node);
void ecommunity_finish(void)
{
- hash_clean(ecomhash, (void (*)(void *))ecommunity_hash_free);
- hash_free(ecomhash);
- ecomhash = NULL;
+ hash_clean_and_free(&ecomhash, (void (*)(void *))ecommunity_hash_free);
}
/* Extended Communities token enum. */
uint8_t ecomm_type;
char buf[INET_ADDRSTRLEN + 1];
struct ecommunity_val *eval = (struct ecommunity_val *)eval_ptr;
+ uint64_t tmp_as = 0;
+
/* Skip white space. */
while (isspace((unsigned char)*p)) {
p++;
goto error;
endptr++;
- as = strtoul(endptr, &endptr, 10);
- if (*endptr != '\0' || as == BGP_AS4_MAX)
+ errno = 0;
+ tmp_as = strtoul(endptr, &endptr, 10);
+ /* 'unsigned long' is a uint64 on 64-bit
+ * systems, and uint32 on 32-bit systems. So for
+ * 64-bit we can just directly check the value
+ * against BGP_AS4_MAX/UINT32_MAX, and for
+ * 32-bit we can check for errno (set to ERANGE
+ * upon overflow).
+ */
+ if (*endptr != '\0' || tmp_as == BGP_AS4_MAX || errno)
goto error;
+ as = (as_t)tmp_as;
memcpy(buf, p, (limit - p));
buf[limit - p] = '\0';
goto error;
} else {
/* ASN */
- as = strtoul(buf, &endptr, 10);
- if (*endptr != '\0' || as == BGP_AS4_MAX)
+ errno = 0;
+ tmp_as = strtoul(buf, &endptr, 10);
+ /* 'unsigned long' is a uint64 on 64-bit
+ * systems, and uint32 on 32-bit systems. So for
+ * 64-bit we can just directly check the value
+ * against BGP_AS4_MAX/UINT32_MAX, and for
+ * 32-bit we can check for errno (set to ERANGE
+ * upon overflow).
+ */
+ if (*endptr != '\0' || tmp_as > BGP_AS4_MAX ||
+ errno)
goto error;
+ as = (as_t)tmp_as;
}
} else if (*p == '.') {
if (separator)
(void (*)(struct hash_bucket *, void *))free_vni_entry,
bgp);
- hash_clean(bgp->import_rt_hash, (void (*)(void *))hash_import_rt_free);
- hash_free(bgp->import_rt_hash);
- bgp->import_rt_hash = NULL;
-
- hash_clean(bgp->vrf_import_rt_hash,
- (void (*)(void *))hash_vrf_import_rt_free);
- hash_free(bgp->vrf_import_rt_hash);
- bgp->vrf_import_rt_hash = NULL;
-
- hash_clean(bgp->vni_svi_hash, (void (*)(void *))hash_evpn_free);
- hash_free(bgp->vni_svi_hash);
- bgp->vni_svi_hash = NULL;
- hash_free(bgp->vnihash);
- bgp->vnihash = NULL;
+ hash_clean_and_free(&bgp->import_rt_hash,
+ (void (*)(void *))hash_import_rt_free);
+
+ hash_clean_and_free(&bgp->vrf_import_rt_hash,
+ (void (*)(void *))hash_vrf_import_rt_free);
+
+ hash_clean_and_free(&bgp->vni_svi_hash,
+ (void (*)(void *))hash_evpn_free);
+
+ /*
+ * Why is the vnihash freed at the top of this function and
+ * then deleted here?
+ */
+ hash_clean_and_free(&bgp->vnihash, NULL);
list_delete(&bgp->vrf_import_rtl);
list_delete(&bgp->vrf_export_rtl);
bool is_local);
esi_t zero_esi_buf, *zero_esi = &zero_esi_buf;
-static void bgp_evpn_run_consistency_checks(struct thread *t);
+static void bgp_evpn_run_consistency_checks(struct event *t);
static void bgp_evpn_path_nh_info_free(struct bgp_path_evpn_nh_info *nh_info);
static void bgp_evpn_path_nh_unlink(struct bgp_path_evpn_nh_info *nh_info);
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
zlog_debug("periodic consistency checking started");
- thread_add_timer(bm->master, bgp_evpn_run_consistency_checks, NULL,
- BGP_EVPN_CONS_CHECK_INTERVAL,
- &bgp_mh_info->t_cons_check);
+ event_add_timer(bm->master, bgp_evpn_run_consistency_checks, NULL,
+ BGP_EVPN_CONS_CHECK_INTERVAL,
+ &bgp_mh_info->t_cons_check);
}
/* queue up the es for background consistency checks */
return proc_cnt;
}
-static void bgp_evpn_run_consistency_checks(struct thread *t)
+static void bgp_evpn_run_consistency_checks(struct event *t)
{
int proc_cnt = 0;
struct listnode *node;
}
/* restart the timer */
- thread_add_timer(bm->master, bgp_evpn_run_consistency_checks, NULL,
+ event_add_timer(bm->master, bgp_evpn_run_consistency_checks, NULL,
BGP_EVPN_CONS_CHECK_INTERVAL,
&bgp_mh_info->t_cons_check);
}
bgp_vrf->evpn_nh_table,
(void (*)(struct hash_bucket *, void *))bgp_evpn_nh_flush_cb,
NULL);
- hash_clean(bgp_vrf->evpn_nh_table, (void (*)(void *))hash_evpn_nh_free);
- hash_free(bgp_vrf->evpn_nh_table);
- bgp_vrf->evpn_nh_table = NULL;
+ hash_clean_and_free(&bgp_vrf->evpn_nh_table,
+ (void (*)(void *))hash_evpn_nh_free);
}
static void bgp_evpn_nh_update_ref_pi(struct bgp_evpn_nh *nh)
bgp_evpn_es_local_info_clear(es, true);
}
if (bgp_mh_info->t_cons_check)
- THREAD_OFF(bgp_mh_info->t_cons_check);
+ EVENT_OFF(bgp_mh_info->t_cons_check);
list_delete(&bgp_mh_info->local_es_list);
list_delete(&bgp_mh_info->pend_es_list);
list_delete(&bgp_mh_info->ead_es_export_rtl);
/* List of ESs with pending/periodic processing */
struct list *pend_es_list;
/* periodic timer for running background consistency checks */
- struct thread *t_cons_check;
+ struct event *t_cons_check;
/* config knobs for optimizing or interop */
/* Generate EAD-EVI routes even if the ES is oper-down. This can be
#include "linklist.h"
#include "prefix.h"
#include "sockunion.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "stream.h"
#include "ringbuf.h"
function. */
/* BGP event function. */
-void bgp_event(struct thread *);
+void bgp_event(struct event *event);
/* BGP thread functions. */
-static void bgp_start_timer(struct thread *);
-static void bgp_connect_timer(struct thread *);
-static void bgp_holdtime_timer(struct thread *);
-static void bgp_delayopen_timer(struct thread *);
+static void bgp_start_timer(struct event *event);
+static void bgp_connect_timer(struct event *event);
+static void bgp_holdtime_timer(struct event *event);
+static void bgp_delayopen_timer(struct event *event);
/* BGP FSM functions. */
static enum bgp_fsm_state_progress bgp_start(struct peer *);
*/
bgp_keepalives_off(from_peer);
- THREAD_OFF(peer->t_routeadv);
- THREAD_OFF(peer->t_connect);
- THREAD_OFF(peer->t_delayopen);
- THREAD_OFF(peer->t_connect_check_r);
- THREAD_OFF(peer->t_connect_check_w);
- THREAD_OFF(from_peer->t_routeadv);
- THREAD_OFF(from_peer->t_connect);
- THREAD_OFF(from_peer->t_delayopen);
- THREAD_OFF(from_peer->t_connect_check_r);
- THREAD_OFF(from_peer->t_connect_check_w);
- THREAD_OFF(from_peer->t_process_packet);
+ EVENT_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_connect_check_r);
+ EVENT_OFF(peer->t_connect_check_w);
+ EVENT_OFF(from_peer->t_routeadv);
+ EVENT_OFF(from_peer->t_connect);
+ EVENT_OFF(from_peer->t_delayopen);
+ EVENT_OFF(from_peer->t_connect_check_r);
+ EVENT_OFF(from_peer->t_connect_check_w);
+ EVENT_OFF(from_peer->t_process_packet);
/*
* At this point in time, it is possible that there are packets pending
bgp_reads_on(peer);
bgp_writes_on(peer);
- thread_add_event(bm->master, bgp_process_packet, peer, 0,
- &peer->t_process_packet);
+ event_add_event(bm->master, bgp_process_packet, peer, 0,
+ &peer->t_process_packet);
return (peer);
}
inactive. All other timer must be turned off */
if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
|| peer->bgp->vrf_id == VRF_UNKNOWN) {
- THREAD_OFF(peer->t_start);
+ EVENT_OFF(peer->t_start);
} else {
BGP_TIMER_ON(peer->t_start, bgp_start_timer,
peer->v_start);
}
- THREAD_OFF(peer->t_connect);
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_holdtime);
bgp_keepalives_off(peer);
- THREAD_OFF(peer->t_routeadv);
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_delayopen);
break;
case Connect:
/* After start timer is expired, the peer moves to Connect
status. Make sure start timer is off and connect timer is
on. */
- THREAD_OFF(peer->t_start);
+ EVENT_OFF(peer->t_start);
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
(peer->v_delayopen + peer->v_connect));
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
peer->v_connect);
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
bgp_keepalives_off(peer);
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
break;
case Active:
/* Active is waiting connection from remote peer. And if
connect timer is expired, change status to Connect. */
- THREAD_OFF(peer->t_start);
+ EVENT_OFF(peer->t_start);
/* If peer is passive mode, do not set connect timer. */
if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)
|| CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
- THREAD_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_connect);
} else {
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
BGP_TIMER_ON(
BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
peer->v_connect);
}
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
bgp_keepalives_off(peer);
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
break;
case OpenSent:
/* OpenSent status. */
- THREAD_OFF(peer->t_start);
- THREAD_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_start);
+ EVENT_OFF(peer->t_connect);
if (peer->v_holdtime != 0) {
BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
peer->v_holdtime);
} else {
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
}
bgp_keepalives_off(peer);
- THREAD_OFF(peer->t_routeadv);
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_delayopen);
break;
case OpenConfirm:
/* OpenConfirm status. */
- THREAD_OFF(peer->t_start);
- THREAD_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_start);
+ EVENT_OFF(peer->t_connect);
/*
* If the negotiated Hold Time value is zero, then the Hold Time
* Additionally if a different hold timer has been negotiated
* than we must stop then start the timer again
*/
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
if (peer->v_holdtime == 0)
bgp_keepalives_off(peer);
else {
peer->v_holdtime);
bgp_keepalives_on(peer);
}
- THREAD_OFF(peer->t_routeadv);
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_delayopen);
break;
case Established:
/* In Established status start and connect timer is turned
off. */
- THREAD_OFF(peer->t_start);
- THREAD_OFF(peer->t_connect);
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_start);
+ EVENT_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_delayopen);
/*
* Same as OpenConfirm, if holdtime is zero then both holdtime
* Additionally if a different hold timer has been negotiated
* then we must stop then start the timer again
*/
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
if (peer->v_holdtime == 0)
bgp_keepalives_off(peer);
else {
}
break;
case Deleted:
- THREAD_OFF(peer->t_gr_restart);
- THREAD_OFF(peer->t_gr_stale);
+ EVENT_OFF(peer->t_gr_restart);
+ EVENT_OFF(peer->t_gr_stale);
FOREACH_AFI_SAFI (afi, safi)
- THREAD_OFF(peer->t_llgr_stale[afi][safi]);
+ EVENT_OFF(peer->t_llgr_stale[afi][safi]);
- THREAD_OFF(peer->t_pmax_restart);
- THREAD_OFF(peer->t_refresh_stalepath);
+ EVENT_OFF(peer->t_pmax_restart);
+ EVENT_OFF(peer->t_refresh_stalepath);
/* fallthru */
case Clearing:
- THREAD_OFF(peer->t_start);
- THREAD_OFF(peer->t_connect);
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_start);
+ EVENT_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_holdtime);
bgp_keepalives_off(peer);
- THREAD_OFF(peer->t_routeadv);
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_delayopen);
break;
case BGP_STATUS_MAX:
flog_err(EC_LIB_DEVELOPMENT,
/* BGP start timer. This function set BGP_Start event to thread value
and process event. */
-static void bgp_start_timer(struct thread *thread)
+static void bgp_start_timer(struct event *thread)
{
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [FSM] Timer (start timer expire).", peer->host);
- THREAD_VAL(thread) = BGP_Start;
+ EVENT_VAL(thread) = BGP_Start;
bgp_event(thread); /* bgp_event unlocks peer */
}
/* BGP connect retry timer. */
-static void bgp_connect_timer(struct thread *thread)
+static void bgp_connect_timer(struct event *thread)
{
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
/* stop the DelayOpenTimer if it is running */
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_delayopen);
assert(!peer->t_write);
assert(!peer->t_read);
if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
bgp_stop(peer);
else {
- THREAD_VAL(thread) = ConnectRetry_timer_expired;
+ EVENT_VAL(thread) = ConnectRetry_timer_expired;
bgp_event(thread); /* bgp_event unlocks peer */
}
}
/* BGP holdtime timer. */
-static void bgp_holdtime_timer(struct thread *thread)
+static void bgp_holdtime_timer(struct event *thread)
{
atomic_size_t inq_count;
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [FSM] Timer (holdtime timer expire)",
BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
peer->v_holdtime);
- THREAD_VAL(thread) = Hold_Timer_expired;
+ EVENT_VAL(thread) = Hold_Timer_expired;
bgp_event(thread); /* bgp_event unlocks peer */
}
-void bgp_routeadv_timer(struct thread *thread)
+void bgp_routeadv_timer(struct event *thread)
{
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [FSM] Timer (routeadv timer expire)",
peer->synctime = monotime(NULL);
- thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0,
- &peer->t_generate_updgrp_packets);
+ event_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0,
+ &peer->t_generate_updgrp_packets);
/* MRAI timer will be started again when FIFO is built, no need to
* do it here.
}
/* RFC 4271 DelayOpenTimer */
-void bgp_delayopen_timer(struct thread *thread)
+void bgp_delayopen_timer(struct event *thread)
{
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [FSM] Timer (DelayOpentimer expire)",
peer->host);
- THREAD_VAL(thread) = DelayOpen_timer_expired;
+ EVENT_VAL(thread) = DelayOpen_timer_expired;
bgp_event(thread); /* bgp_event unlocks peer */
}
return;
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
- THREAD_OFF(peer->t_gr_stale);
+ EVENT_OFF(peer->t_gr_stale);
if (peer_dynamic_neighbor(peer) &&
!(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
bgp_timer_set(peer);
}
-static void bgp_llgr_stale_timer_expire(struct thread *thread)
+static void bgp_llgr_stale_timer_expire(struct event *thread)
{
struct peer_af *paf;
struct peer *peer;
afi_t afi;
safi_t safi;
- paf = THREAD_ARG(thread);
+ paf = EVENT_ARG(thread);
peer = paf->peer;
afi = paf->afi;
}
}
-static void bgp_graceful_restart_timer_expire(struct thread *thread)
+static void bgp_graceful_restart_timer_expire(struct event *thread)
{
struct peer *peer, *tmp_peer;
struct listnode *node, *nnode;
afi_t afi;
safi_t safi;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (bgp_debug_neighbor_events(peer)) {
zlog_debug("%pBP graceful restart timer expired", peer);
bgp_set_llgr_stale(peer, afi, safi);
bgp_clear_stale_route(peer, afi, safi);
- thread_add_timer(bm->master,
- bgp_llgr_stale_timer_expire, paf,
- peer->llgr[afi][safi].stale_time,
- &peer->t_llgr_stale[afi][safi]);
+ event_add_timer(bm->master, bgp_llgr_stale_timer_expire,
+ paf, peer->llgr[afi][safi].stale_time,
+ &peer->t_llgr_stale[afi][safi]);
for (ALL_LIST_ELEMENTS(peer->bgp->peer, node, nnode,
tmp_peer))
bgp_graceful_restart_timer_off(peer);
}
-static void bgp_graceful_stale_timer_expire(struct thread *thread)
+static void bgp_graceful_stale_timer_expire(struct event *thread)
{
struct peer *peer;
afi_t afi;
safi_t safi;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%pBP graceful restart stalepath timer expired",
}
/* Selection deferral timer processing function */
-static void bgp_graceful_deferral_timer_expire(struct thread *thread)
+static void bgp_graceful_deferral_timer_expire(struct event *thread)
{
struct afi_safi_info *info;
afi_t afi;
safi_t safi;
struct bgp *bgp;
- info = THREAD_ARG(thread);
+ info = EVENT_ARG(thread);
afi = info->afi;
safi = info->safi;
bgp = info->bgp;
on ending the update delay. */
void bgp_update_delay_end(struct bgp *bgp)
{
- THREAD_OFF(bgp->t_update_delay);
- THREAD_OFF(bgp->t_establish_wait);
+ EVENT_OFF(bgp->t_update_delay);
+ EVENT_OFF(bgp->t_establish_wait);
/* Reset update-delay related state */
bgp->update_delay_over = 1;
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!peer_established(peer))
continue;
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
}
}
* different
* duration and schedule write thread immediately.
*/
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
peer->synctime = monotime(NULL);
/* If suppress fib pending is enabled, route is advertised to
*/
diff = difftime(nowtime, peer->last_update);
if (diff > (double)peer->v_routeadv) {
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
return;
}
* (MRAI - m) < r
*/
if (peer->t_routeadv)
- remain = thread_timer_remain_second(peer->t_routeadv);
+ remain = event_timer_remain_second(peer->t_routeadv);
else
remain = peer->v_routeadv;
diff = peer->v_routeadv - diff;
if (diff <= (double)remain) {
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
}
}
}
/* The maxmed onstartup timer expiry callback. */
-static void bgp_maxmed_onstartup_timer(struct thread *thread)
+static void bgp_maxmed_onstartup_timer(struct event *thread)
{
struct bgp *bgp;
zlog_info("Max med on startup ended - timer expired.");
- bgp = THREAD_ARG(thread);
- THREAD_OFF(bgp->t_maxmed_onstartup);
+ bgp = EVENT_ARG(thread);
+ EVENT_OFF(bgp->t_maxmed_onstartup);
bgp->maxmed_onstartup_over = 1;
bgp_maxmed_update(bgp);
zlog_info("Begin maxmed onstartup mode - timer %d seconds",
bgp->v_maxmed_onstartup);
- thread_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
- bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
+ event_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
+ bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
if (!bgp->v_maxmed_admin) {
bgp->maxmed_active = 1;
}
/* The update delay timer expiry callback. */
-static void bgp_update_delay_timer(struct thread *thread)
+static void bgp_update_delay_timer(struct event *thread)
{
struct bgp *bgp;
zlog_info("Update delay ended - timer expired.");
- bgp = THREAD_ARG(thread);
- THREAD_OFF(bgp->t_update_delay);
+ bgp = EVENT_ARG(thread);
+ EVENT_OFF(bgp->t_update_delay);
bgp_update_delay_end(bgp);
}
/* The establish wait timer expiry callback. */
-static void bgp_establish_wait_timer(struct thread *thread)
+static void bgp_establish_wait_timer(struct event *thread)
{
struct bgp *bgp;
zlog_info("Establish wait - timer expired.");
- bgp = THREAD_ARG(thread);
- THREAD_OFF(bgp->t_establish_wait);
+ bgp = EVENT_ARG(thread);
+ EVENT_OFF(bgp->t_establish_wait);
bgp_check_update_delay(bgp);
}
peer->update_delay_over = 0;
/* Start the update-delay timer */
- thread_add_timer(bm->master, bgp_update_delay_timer, bgp,
- bgp->v_update_delay, &bgp->t_update_delay);
+ event_add_timer(bm->master, bgp_update_delay_timer, bgp,
+ bgp->v_update_delay, &bgp->t_update_delay);
if (bgp->v_establish_wait != bgp->v_update_delay)
- thread_add_timer(bm->master, bgp_establish_wait_timer, bgp,
- bgp->v_establish_wait, &bgp->t_establish_wait);
+ event_add_timer(bm->master, bgp_establish_wait_timer, bgp,
+ bgp->v_establish_wait, &bgp->t_establish_wait);
frr_timestamp(3, bgp->update_delay_begin_time,
sizeof(bgp->update_delay_begin_time));
/* graceful restart */
if (peer->t_gr_stale) {
- THREAD_OFF(peer->t_gr_stale);
+ EVENT_OFF(peer->t_gr_stale);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP graceful restart stalepath timer stopped",
/* Stop route-refresh stalepath timer */
if (peer->t_refresh_stalepath) {
- THREAD_OFF(peer->t_refresh_stalepath);
+ EVENT_OFF(peer->t_refresh_stalepath);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
/* There is no pending EOR message */
if (gr_info->eor_required == 0) {
if (gr_info->t_select_deferral) {
- void *info = THREAD_ARG(
+ void *info = EVENT_ARG(
gr_info->t_select_deferral);
XFREE(MTYPE_TMP, info);
}
- THREAD_OFF(gr_info->t_select_deferral);
+ EVENT_OFF(gr_info->t_select_deferral);
gr_info->eor_received = 0;
}
}
bgp_writes_off(peer);
bgp_reads_off(peer);
- THREAD_OFF(peer->t_connect_check_r);
- THREAD_OFF(peer->t_connect_check_w);
+ EVENT_OFF(peer->t_connect_check_r);
+ EVENT_OFF(peer->t_connect_check_w);
/* Stop all timers. */
- THREAD_OFF(peer->t_start);
- THREAD_OFF(peer->t_connect);
- THREAD_OFF(peer->t_holdtime);
- THREAD_OFF(peer->t_routeadv);
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_start);
+ EVENT_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_delayopen);
/* Clear input and output buffer. */
frr_with_mutex (&peer->io_mtx) {
* when the connection is established. A read event is triggered when the
* connection is closed. Thus we need to cancel whichever one did not occur.
*/
-static void bgp_connect_check(struct thread *thread)
+static void bgp_connect_check(struct event *thread)
{
int status;
socklen_t slen;
int ret;
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
assert(!peer->t_read);
assert(!peer->t_write);
- THREAD_OFF(peer->t_connect_check_r);
- THREAD_OFF(peer->t_connect_check_w);
+ EVENT_OFF(peer->t_connect_check_r);
+ EVENT_OFF(peer->t_connect_check_w);
/* Check file descriptor. */
slen = sizeof(status);
* bgp_connect_check() as the handler for each and cancel the
* unused event in that function.
*/
- thread_add_read(bm->master, bgp_connect_check, peer, peer->fd,
- &peer->t_connect_check_r);
- thread_add_write(bm->master, bgp_connect_check, peer, peer->fd,
- &peer->t_connect_check_w);
+ event_add_read(bm->master, bgp_connect_check, peer, peer->fd,
+ &peer->t_connect_check_r);
+ event_add_write(bm->master, bgp_connect_check, peer, peer->fd,
+ &peer->t_connect_check_w);
break;
}
return BGP_FSM_SUCCESS;
bgp_fsm_delayopen_timer_expire(struct peer *peer)
{
/* Stop the DelayOpenTimer */
- THREAD_OFF(peer->t_delayopen);
+ EVENT_OFF(peer->t_delayopen);
/* Send open message to peer */
bgp_open_send(peer);
thread_info->safi = safi;
thread_info->bgp = bgp;
- thread_add_timer(bm->master, bgp_graceful_deferral_timer_expire,
- thread_info, bgp->select_defer_time,
- &gr_info->t_select_deferral);
+ event_add_timer(bm->master, bgp_graceful_deferral_timer_expire,
+ thread_info, bgp->select_defer_time,
+ &gr_info->t_select_deferral);
}
gr_info->eor_required++;
/* Send message to RIB indicating route update pending */
else {
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
if (peer->t_gr_stale) {
- THREAD_OFF(peer->t_gr_stale);
+ EVENT_OFF(peer->t_gr_stale);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP graceful restart stalepath timer stopped",
}
if (peer->t_gr_restart) {
- THREAD_OFF(peer->t_gr_restart);
+ EVENT_OFF(peer->t_gr_restart);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%pBP graceful restart timer stopped", peer);
}
*/
FOREACH_AFI_SAFI (afi, safi) {
if (peer->t_llgr_stale[afi][safi]) {
- THREAD_OFF(peer->t_llgr_stale[afi][safi]);
+ EVENT_OFF(peer->t_llgr_stale[afi][safi]);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
* of read-only mode.
*/
if (!bgp_update_delay_active(peer->bgp)) {
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
}
/* Keepalive packet is received. */
static enum bgp_fsm_state_progress bgp_fsm_keepalive(struct peer *peer)
{
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
return BGP_FSM_SUCCESS;
}
/* Update packet is received. */
static enum bgp_fsm_state_progress bgp_fsm_update(struct peer *peer)
{
- THREAD_OFF(peer->t_holdtime);
+ EVENT_OFF(peer->t_holdtime);
return BGP_FSM_SUCCESS;
}
break;
case Connect:
if (!has_valid_nexthops) {
- THREAD_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_connect);
BGP_EVENT_ADD(peer, TCP_fatal_error);
}
break;
case Active:
if (has_valid_nexthops) {
- THREAD_OFF(peer->t_connect);
+ EVENT_OFF(peer->t_connect);
BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
}
break;
};
/* Execute event process. */
-void bgp_event(struct thread *thread)
+void bgp_event(struct event *thread)
{
enum bgp_fsm_events event;
struct peer *peer;
- peer = THREAD_ARG(thread);
- event = THREAD_VAL(thread);
+ peer = EVENT_ARG(thread);
+ event = EVENT_VAL(thread);
peer_lock(peer);
bgp_event_update(peer, event);
#define BGP_TIMER_ON(T, F, V) \
do { \
if ((peer->status != Deleted)) \
- thread_add_timer(bm->master, (F), peer, (V), &(T)); \
+ event_add_timer(bm->master, (F), peer, (V), &(T)); \
} while (0)
#define BGP_EVENT_ADD(P, E) \
do { \
if ((P)->status != Deleted) \
- thread_add_event(bm->master, bgp_event, (P), (E), \
- NULL); \
+ event_add_event(bm->master, bgp_event, (P), (E), \
+ NULL); \
} while (0)
#define BGP_EVENT_FLUSH(P) \
do { \
assert(peer); \
- thread_cancel_event_ready(bm->master, (P)); \
+ event_cancel_event_ready(bm->master, (P)); \
} while (0)
-#define BGP_UPDATE_GROUP_TIMER_ON(T, F) \
- do { \
- if (BGP_SUPPRESS_FIB_ENABLED(peer->bgp) && \
- PEER_ROUTE_ADV_DELAY(peer)) \
- thread_add_timer_msec(bm->master, (F), peer, \
- (BGP_DEFAULT_UPDATE_ADVERTISEMENT_TIME * 1000),\
- (T)); \
- else \
- thread_add_timer_msec(bm->master, (F), peer, \
- 0, (T)); \
- } while (0) \
+#define BGP_UPDATE_GROUP_TIMER_ON(T, F) \
+ do { \
+ if (BGP_SUPPRESS_FIB_ENABLED(peer->bgp) && \
+ PEER_ROUTE_ADV_DELAY(peer)) \
+ event_add_timer_msec( \
+ bm->master, (F), peer, \
+ (BGP_DEFAULT_UPDATE_ADVERTISEMENT_TIME * \
+ 1000), \
+ (T)); \
+ else \
+ event_add_timer_msec(bm->master, (F), peer, 0, (T)); \
+ } while (0)
#define BGP_MSEC_JITTER 10
* Update FSM for peer based on whether we have valid nexthops or not.
*/
extern void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops);
-extern void bgp_event(struct thread *);
+extern void bgp_event(struct event *event);
extern int bgp_event_update(struct peer *, enum bgp_fsm_events event);
extern int bgp_stop(struct peer *peer);
extern void bgp_timer_set(struct peer *);
-extern void bgp_routeadv_timer(struct thread *);
+extern void bgp_routeadv_timer(struct event *event);
extern void bgp_fsm_change_status(struct peer *peer,
enum bgp_fsm_status status);
extern const char *const peer_down_str[];
#include "network.h" // for ERRNO_IO_RETRY
#include "stream.h" // for stream_get_endp, stream_getw_from, str...
#include "ringbuf.h" // for ringbuf_remain, ringbuf_peek, ringbuf_...
-#include "thread.h" // for THREAD_OFF, THREAD_ARG, thread...
+#include "frrevent.h" // for EVENT_OFF, EVENT_ARG, thread...
#include "bgpd/bgp_io.h"
#include "bgpd/bgp_debug.h" // for bgp_debug_neighbor_events, bgp_type_str
/* forward declarations */
static uint16_t bgp_write(struct peer *);
static uint16_t bgp_read(struct peer *peer, int *code_p);
-static void bgp_process_writes(struct thread *);
-static void bgp_process_reads(struct thread *);
+static void bgp_process_writes(struct event *event);
+static void bgp_process_reads(struct event *event);
static bool validate_header(struct peer *);
/* generic i/o status codes */
assert(!peer->t_connect_check_w);
assert(peer->fd);
- thread_add_write(fpt->master, bgp_process_writes, peer, peer->fd,
- &peer->t_write);
+ event_add_write(fpt->master, bgp_process_writes, peer, peer->fd,
+ &peer->t_write);
SET_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON);
}
struct frr_pthread *fpt = bgp_pth_io;
assert(fpt->running);
- thread_cancel_async(fpt->master, &peer->t_write, NULL);
- THREAD_OFF(peer->t_generate_updgrp_packets);
+ event_cancel_async(fpt->master, &peer->t_write, NULL);
+ EVENT_OFF(peer->t_generate_updgrp_packets);
UNSET_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON);
}
assert(!peer->t_connect_check_w);
assert(peer->fd);
- thread_add_read(fpt->master, bgp_process_reads, peer, peer->fd,
- &peer->t_read);
+ event_add_read(fpt->master, bgp_process_reads, peer, peer->fd,
+ &peer->t_read);
SET_FLAG(peer->thread_flags, PEER_THREAD_READS_ON);
}
struct frr_pthread *fpt = bgp_pth_io;
assert(fpt->running);
- thread_cancel_async(fpt->master, &peer->t_read, NULL);
- THREAD_OFF(peer->t_process_packet);
- THREAD_OFF(peer->t_process_packet_error);
+ event_cancel_async(fpt->master, &peer->t_read, NULL);
+ EVENT_OFF(peer->t_process_packet);
+ EVENT_OFF(peer->t_process_packet_error);
UNSET_FLAG(peer->thread_flags, PEER_THREAD_READS_ON);
}
/*
* Called from I/O pthread when a file descriptor has become ready for writing.
*/
-static void bgp_process_writes(struct thread *thread)
+static void bgp_process_writes(struct event *thread)
{
static struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
uint16_t status;
bool reschedule;
bool fatal = false;
* sent in the update message
*/
if (reschedule) {
- thread_add_write(fpt->master, bgp_process_writes, peer,
- peer->fd, &peer->t_write);
+ event_add_write(fpt->master, bgp_process_writes, peer, peer->fd,
+ &peer->t_write);
} else if (!fatal) {
BGP_UPDATE_GROUP_TIMER_ON(&peer->t_generate_updgrp_packets,
bgp_generate_updgrp_packets);
* We read as much data as possible, process as many packets as we can and
* place them on peer->ibuf for secondary processing by the main thread.
*/
-static void bgp_process_reads(struct thread *thread)
+static void bgp_process_reads(struct event *thread)
{
/* clang-format off */
static struct peer *peer; /* peer to read from */
int ret = 1;
/* clang-format on */
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
if (peer->fd < 0 || bm->terminating)
return;
/* Handle the error in the main pthread, include the
* specific state change from 'bgp_read'.
*/
- thread_add_event(bm->master, bgp_packet_process_error,
- peer, code, &peer->t_process_packet_error);
+ event_add_event(bm->master, bgp_packet_process_error, peer,
+ code, &peer->t_process_packet_error);
goto done;
}
if (!ibuf_full)
assert(ringbuf_space(peer->ibuf_work) >= peer->max_packet_size);
- thread_add_read(fpt->master, bgp_process_reads, peer, peer->fd,
- &peer->t_read);
+ event_add_read(fpt->master, bgp_process_reads, peer, peer->fd,
+ &peer->t_read);
if (added_pkt)
- thread_add_event(bm->master, bgp_process_packet, peer, 0,
- &peer->t_process_packet);
+ event_add_event(bm->master, bgp_process_packet, peer, 0,
+ &peer->t_process_packet);
}
/*
#include "memory.h" // for MTYPE_TMP, XFREE, XCALLOC, XMALLOC
#include "monotime.h" // for monotime, monotime_since
-#include "bgpd/bgpd.h" // for peer, PEER_THREAD_KEEPALIVES_ON, peer...
+#include "bgpd/bgpd.h" // for peer, PEER_EVENT_KEEPALIVES_ON, peer...
#include "bgpd/bgp_debug.h" // for bgp_debug_neighbor_events
#include "bgpd/bgp_packet.h" // for bgp_keepalive_send
#include "bgpd/bgp_keepalives.h"
/* Cleanup handler / deinitializer. */
static void bgp_keepalives_finish(void *arg)
{
- if (peerhash) {
- hash_clean(peerhash, pkat_del);
- hash_free(peerhash);
- }
-
- peerhash = NULL;
+ hash_clean_and_free(&peerhash, pkat_del);
pthread_mutex_unlock(peerhash_mtx);
pthread_mutex_destroy(peerhash_mtx);
/*
* The RCU mechanism for each pthread is initialized in a "locked"
* state. That's ok for pthreads using the frr_pthread,
- * thread_fetch event loop, because that event loop unlocks regularly.
+ * event_fetch event loop, because that event loop unlocks regularly.
* For foreign pthreads, the lock needs to be unlocked so that the
* background rcu pthread can run.
*/
#include <zebra.h>
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "zclient.h"
#include "stream.h"
XFREE(MTYPE_BGP_LABEL_CHUNK, goner);
}
-void bgp_lp_init(struct thread_master *master, struct labelpool *pool)
+void bgp_lp_init(struct event_loop *master, struct labelpool *pool)
{
if (BGP_DEBUG(labelpool, LABELPOOL))
zlog_debug("%s: entry", __func__);
struct timeval starttime;
struct skiplist *timestamps_alloc;
struct skiplist *timestamps_dealloc;
- struct thread *event_thread;
+ struct event *event_thread;
unsigned int counter[LPT_STAT_MAX];
};
return 0;
}
-static void labelpool_test_event_handler(struct thread *thread)
+static void labelpool_test_event_handler(struct event *thread)
{
struct lp_test *tcb;
}
if (tcb->event_thread)
- thread_cancel(&tcb->event_thread);
+ event_cancel(&tcb->event_thread);
lpt_inprogress = false;
}
}
if (tcb->event_thread)
- thread_cancel(&tcb->event_thread);
+ event_cancel(&tcb->event_thread);
memset(tcb, 0, sizeof(*tcb));
uint32_t next_chunksize; /* request this many labels */
};
-extern void bgp_lp_init(struct thread_master *master, struct labelpool *pool);
+extern void bgp_lp_init(struct event_loop *master, struct labelpool *pool);
extern void bgp_lp_finish(void);
extern void bgp_lp_get(int type, void *labelid,
int (*cbfunc)(mpls_label_t label, void *labelid, bool allocated));
void lcommunity_finish(void)
{
- hash_clean(lcomhash, (void (*)(void *))lcommunity_hash_free);
- hash_free(lcomhash);
- lcomhash = NULL;
+ hash_clean_and_free(&lcomhash, (void (*)(void *))lcommunity_hash_free);
}
/* Get next Large Communities token from the string.
void bgp_mac_finish(void)
{
- hash_clean(bm->self_mac_hash, bgp_mac_hash_free);
- hash_free(bm->self_mac_hash);
+ hash_clean_and_free(&bm->self_mac_hash, bgp_mac_hash_free);
}
static void bgp_mac_hash_interface_string_del(void *val)
#include "vector.h"
#include "command.h"
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include <lib/version.h>
#include "memory.h"
#include "prefix.h"
#include "log.h"
#include "prefix.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "smux.h"
#include "filter.h"
#include "hook.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "sockunion.h"
#include "sockopt.h"
#include "memory.h"
}
/* Accept bgp connection. */
-static void bgp_accept(struct thread *thread)
+static void bgp_accept(struct event *thread)
{
int bgp_sock;
int accept_sock;
union sockunion su;
- struct bgp_listener *listener = THREAD_ARG(thread);
+ struct bgp_listener *listener = EVENT_ARG(thread);
struct peer *peer;
struct peer *peer1;
char buf[SU_ADDRSTRLEN];
bgp = bgp_lookup_by_name(listener->name);
/* Register accept thread. */
- accept_sock = THREAD_FD(thread);
+ accept_sock = EVENT_FD(thread);
if (accept_sock < 0) {
flog_err_sys(EC_LIB_SOCKET,
"[Error] BGP accept socket fd is negative: %d",
return;
}
- thread_add_read(bm->master, bgp_accept, listener, accept_sock,
- &listener->thread);
+ event_add_read(bm->master, bgp_accept, listener, accept_sock,
+ &listener->thread);
/* Accept client connection. */
bgp_sock = sockunion_accept(accept_sock, &su);
"[Error] accept() failed with error \"%s\" on BGP listener socket %d for BGP instance in VRF \"%s\"; refreshing socket",
safe_strerror(save_errno), accept_sock,
VRF_LOGNAME(vrf));
- THREAD_OFF(listener->thread);
+ EVENT_OFF(listener->thread);
} else {
flog_err_sys(
EC_LIB_SOCKET,
sockopt_tcp_mss_set(bgp_sock, peer1->tcp_mss);
bgp_fsm_change_status(peer1, Active);
- THREAD_OFF(
+ EVENT_OFF(
peer1->t_start); /* created in peer_create() */
if (peer_active(peer1)) {
}
bgp_peer_reg_with_nht(peer);
bgp_fsm_change_status(peer, Active);
- THREAD_OFF(peer->t_start); /* created in peer_create() */
+ EVENT_OFF(peer->t_start); /* created in peer_create() */
SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
/* Make dummy peer until read Open packet. */
? IPV4_MAX_BITLEN
: IPV6_MAX_BITLEN;
+ if (!BGP_PEER_SU_UNSPEC(peer))
+ bgp_md5_set(peer);
+
bgp_md5_set_connect(peer->fd, &peer->su, prefixlen,
peer->password);
}
listener->bgp = bgp;
memcpy(&listener->su, sa, salen);
- thread_add_read(bm->master, bgp_accept, listener, sock,
- &listener->thread);
+ event_add_read(bm->master, bgp_accept, listener, sock,
+ &listener->thread);
listnode_add(bm->listen_sockets, listener);
return 0;
for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
if (listener->bgp == bgp) {
- THREAD_OFF(listener->thread);
+ EVENT_OFF(listener->thread);
close(listener->fd);
listnode_delete(bm->listen_sockets, listener);
XFREE(MTYPE_BGP_LISTENER, listener->name);
for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
if (listener->bgp)
continue;
- THREAD_OFF(listener->thread);
+ EVENT_OFF(listener->thread);
close(listener->fd);
listnode_delete(bm->listen_sockets, listener);
XFREE(MTYPE_BGP_LISTENER, listener->name);
struct bgp_listener {
int fd;
union sockunion su;
- struct thread *thread;
+ struct event *thread;
struct bgp *bgp;
char *name;
};
#include <zebra.h>
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "lib/json.h"
#include "zclient.h"
void bgp_tip_hash_destroy(struct bgp *bgp)
{
- if (bgp->tip_hash == NULL)
- return;
- hash_clean(bgp->tip_hash, bgp_tip_hash_free);
- hash_free(bgp->tip_hash);
- bgp->tip_hash = NULL;
+ hash_clean_and_free(&bgp->tip_hash, bgp_tip_hash_free);
}
/* Add/Update Tunnel-IP entry of bgp martian next-hop table.
void bgp_address_destroy(struct bgp *bgp)
{
- if (bgp->address_hash == NULL)
- return;
- hash_clean(bgp->address_hash, bgp_address_hash_free);
- hash_free(bgp->address_hash);
- bgp->address_hash = NULL;
+ hash_clean_and_free(&bgp->address_hash, bgp_address_hash_free);
}
static void bgp_address_add(struct bgp *bgp, struct connected *ifc,
#include <zebra.h>
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "zclient.h"
#include "stream.h"
static void register_zebra_rnh(struct bgp_nexthop_cache *bnc);
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc);
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
-static void bgp_nht_ifp_initial(struct thread *thread);
+static void bgp_nht_ifp_initial(struct event *thread);
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
{
bgp_nht_ifp_handle(ifp, false);
}
-static void bgp_nht_ifp_initial(struct thread *thread)
+static void bgp_nht_ifp_initial(struct event *thread)
{
- ifindex_t ifindex = THREAD_VAL(thread);
- struct bgp *bgp = THREAD_ARG(thread);
+ ifindex_t ifindex = EVENT_VAL(thread);
+ struct bgp *bgp = EVENT_ARG(thread);
struct interface *ifp = if_lookup_by_index(ifindex, bgp->vrf_id);
if (!ifp)
return;
if (bnc->ifindex)
- thread_add_event(bm->master, bgp_nht_ifp_initial, bnc->bgp,
- bnc->ifindex, NULL);
+ event_add_event(bm->master, bgp_nht_ifp_initial, bnc->bgp,
+ bnc->ifindex, NULL);
}
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
#include "linklist.h"
#include "prefix.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "command.h"
#include "memory.h"
static int bgp_capability_llgr(struct peer *peer,
struct capability_header *caphdr)
{
+/*
+ * +--------------------------------------------------+
+ * | Address Family Identifier (16 bits) |
+ * +--------------------------------------------------+
+ * | Subsequent Address Family Identifier (8 bits) |
+ * +--------------------------------------------------+
+ * | Flags for Address Family (8 bits) |
+ * +--------------------------------------------------+
+ * | Long-lived Stale Time (24 bits) |
+ * +--------------------------------------------------+
+ */
+#define BGP_CAP_LLGR_MIN_PACKET_LEN 7
struct stream *s = BGP_INPUT(peer);
size_t end = stream_get_getp(s) + caphdr->length;
SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV);
- while (stream_get_getp(s) + 4 <= end) {
+ while (stream_get_getp(s) + BGP_CAP_LLGR_MIN_PACKET_LEN <= end) {
afi_t afi;
safi_t safi;
iana_afi_t pkt_afi = stream_getw(s);
#include <zebra.h>
#include <sys/time.h>
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#include "network.h"
#include "prefix.h"
* update group a peer belongs to, encode this information into packets, and
* enqueue the packets onto the peer's output buffer.
*/
-void bgp_generate_updgrp_packets(struct thread *thread)
+void bgp_generate_updgrp_packets(struct event *thread)
{
- struct peer *peer = THREAD_ARG(thread);
+ struct peer *peer = EVENT_ARG(thread);
struct stream *s;
struct peer_af *paf;
return Receive_KEEPALIVE_message;
}
-static void bgp_refresh_stalepath_timer_expire(struct thread *thread)
+static void bgp_refresh_stalepath_timer_expire(struct event *thread)
{
struct peer_af *paf;
- paf = THREAD_ARG(thread);
+ paf = EVENT_ARG(thread);
afi_t afi = paf->afi;
safi_t safi = paf->safi;
"EOR RCV",
gr_info->eor_received);
if (gr_info->t_select_deferral) {
- void *info = THREAD_ARG(
+ void *info = EVENT_ARG(
gr_info->t_select_deferral);
XFREE(MTYPE_TMP, info);
}
- THREAD_OFF(gr_info->t_select_deferral);
+ EVENT_OFF(gr_info->t_select_deferral);
gr_info->eor_required = 0;
gr_info->eor_received = 0;
/* Best path selection */
}
if (peer_established(peer))
- thread_add_timer(bm->master,
- bgp_refresh_stalepath_timer_expire,
- paf, peer->bgp->stalepath_time,
- &peer->t_refresh_stalepath);
+ event_add_timer(bm->master,
+ bgp_refresh_stalepath_timer_expire, paf,
+ peer->bgp->stalepath_time,
+ &peer->t_refresh_stalepath);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
return BGP_PACKET_NOOP;
}
- THREAD_OFF(peer->t_refresh_stalepath);
+ EVENT_OFF(peer->t_refresh_stalepath);
SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_RECEIVED);
UNSET_FLAG(peer->af_sflags[afi][safi],
* would not, making event flow difficult to understand. Please think twice
* before hacking this.
*
- * Thread type: THREAD_EVENT
+ * Thread type: EVENT_EVENT
* @param thread
* @return 0
*/
-void bgp_process_packet(struct thread *thread)
+void bgp_process_packet(struct event *thread)
{
/* Yes first of all get peer pointer. */
struct peer *peer; // peer
int fsm_update_result; // return code of bgp_event_update()
int mprc; // message processing return code
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
rpkt_quanta_old = atomic_load_explicit(&peer->bgp->rpkt_quanta,
memory_order_relaxed);
fsm_update_result = 0;
frr_with_mutex (&peer->io_mtx) {
// more work to do, come back later
if (peer->ibuf->count > 0)
- thread_add_event(
- bm->master, bgp_process_packet, peer, 0,
- &peer->t_process_packet);
+ event_add_event(bm->master, bgp_process_packet,
+ peer, 0,
+ &peer->t_process_packet);
}
}
}
* having the io pthread try to enqueue fsm events or mess with the peer
* struct.
*/
-void bgp_packet_process_error(struct thread *thread)
+void bgp_packet_process_error(struct event *thread)
{
struct peer *peer;
int code;
- peer = THREAD_ARG(thread);
- code = THREAD_VAL(thread);
+ peer = EVENT_ARG(thread);
+ code = EVENT_VAL(thread);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [Event] BGP error %d on fd %d",
extern int bgp_packet_set_marker(struct stream *s, uint8_t type);
extern void bgp_packet_set_size(struct stream *s);
-extern void bgp_generate_updgrp_packets(struct thread *);
-extern void bgp_process_packet(struct thread *);
+extern void bgp_generate_updgrp_packets(struct event *event);
+extern void bgp_process_packet(struct event *event);
extern void bgp_send_delayed_eor(struct bgp *bgp);
/* Task callback to handle socket error encountered in the io pthread */
-void bgp_packet_process_error(struct thread *thread);
+void bgp_packet_process_error(struct event *thread);
extern struct bgp_notify
bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify);
extern bool bgp_has_graceful_restart_notification(struct peer *peer);
bpm->action = NULL;
}
}
- hash_free(bpm->entry_hash);
+ hash_clean_and_free(&bpm->entry_hash, NULL);
XFREE(MTYPE_PBR_MATCH, bpm);
}
void bgp_pbr_cleanup(struct bgp *bgp)
{
- if (bgp->pbr_match_hash) {
- hash_clean(bgp->pbr_match_hash, bgp_pbr_match_free);
- hash_free(bgp->pbr_match_hash);
- bgp->pbr_match_hash = NULL;
- }
- if (bgp->pbr_rule_hash) {
- hash_clean(bgp->pbr_rule_hash, bgp_pbr_rule_free);
- hash_free(bgp->pbr_rule_hash);
- bgp->pbr_rule_hash = NULL;
- }
- if (bgp->pbr_action_hash) {
- hash_clean(bgp->pbr_action_hash, bgp_pbr_action_free);
- hash_free(bgp->pbr_action_hash);
- bgp->pbr_action_hash = NULL;
- }
+ hash_clean_and_free(&bgp->pbr_match_hash, bgp_pbr_match_free);
+ hash_clean_and_free(&bgp->pbr_rule_hash, bgp_pbr_rule_free);
+ hash_clean_and_free(&bgp->pbr_action_hash, bgp_pbr_action_free);
+
if (bgp->bgp_pbr_cfg == NULL)
return;
+
bgp_pbr_reset(bgp, AFI_IP);
bgp_pbr_reset(bgp, AFI_IP6);
XFREE(MTYPE_PBR, bgp->bgp_pbr_cfg);
#include "buffer.h"
#include "sockunion.h"
#include "plist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "workqueue.h"
#include "queue.h"
#include "memory.h"
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
zlog_debug(
"%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
- peer, p, ROUTE_MAP_OUT_NAME(filter));
+ peer, p,
+ bgp_path_suppressed(pi)
+ ? UNSUPPRESS_MAP_NAME(filter)
+ : ROUTE_MAP_OUT_NAME(filter));
bgp_attr_flush(rmap_path.attr);
return false;
}
return true;
}
-static void bgp_route_select_timer_expire(struct thread *thread)
+static void bgp_route_select_timer_expire(struct event *thread)
{
struct afi_safi_info *info;
afi_t afi;
safi_t safi;
struct bgp *bgp;
- info = THREAD_ARG(thread);
+ info = EVENT_ARG(thread);
afi = info->afi;
safi = info->safi;
bgp = info->bgp;
if (bgp_fibupd_safi(safi)
&& !bgp_option_check(BGP_OPT_NO_FIB)) {
- if (BGP_SUPPRESS_FIB_ENABLED(bgp)
- && new_select->sub_type == BGP_ROUTE_NORMAL)
- SET_FLAG(dest->flags,
- BGP_NODE_FIB_INSTALL_PENDING);
-
if (new_select->type == ZEBRA_ROUTE_BGP
&& (new_select->sub_type == BGP_ROUTE_NORMAL
|| new_select->sub_type
if (!bgp->t_rmap_def_originate_eval) {
bgp_lock(bgp);
- thread_add_timer(
+ event_add_timer(
bm->master,
update_group_refresh_default_originate_route_map,
bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
|| new_select->sub_type == BGP_ROUTE_AGGREGATE
|| new_select->sub_type == BGP_ROUTE_IMPORTED)) {
- if (BGP_SUPPRESS_FIB_ENABLED(bgp))
- SET_FLAG(dest->flags,
- BGP_NODE_FIB_INSTALL_PENDING);
-
/* if this is an evpn imported type-5 prefix,
* we need to withdraw the route first to clear
* the nh neigh and the RMAC entry.
struct afi_safi_info *thread_info;
if (bgp->gr_info[afi][safi].t_route_select) {
- struct thread *t = bgp->gr_info[afi][safi].t_route_select;
+ struct event *t = bgp->gr_info[afi][safi].t_route_select;
- thread_info = THREAD_ARG(t);
+ thread_info = EVENT_ARG(t);
XFREE(MTYPE_TMP, thread_info);
- THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
+ EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
}
if (BGP_DEBUG(update, UPDATE_OUT)) {
/* If there are more routes to be processed, start the
* selection timer
*/
- thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
+ event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
BGP_ROUTE_SELECT_DELAY,
&bgp->gr_info[afi][safi].t_route_select);
}
work_queue_add(bgp->process_queue, pqnode);
}
-static void bgp_maximum_prefix_restart_timer(struct thread *thread)
+static void bgp_maximum_prefix_restart_timer(struct event *thread)
{
struct peer *peer;
- peer = THREAD_ARG(thread);
+ peer = EVENT_ARG(thread);
peer->t_pmax_restart = NULL;
if (bgp_debug_neighbor_events(peer))
(type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
: false;
+ /* If `bgp allow-martian-nexthop` is turned on, return next-hop
+ * as good.
+ */
+ if (bgp->allow_martian)
+ return false;
+
/*
* Only validated for unicast and multicast currently.
* Also valid for EVPN where the nexthop is an IP address.
bgp_attr_flush(&new_attr);
goto filtered;
}
- /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
- * condition :
- * Suppress fib is enabled
- * BGP_OPT_NO_FIB is not enabled
- * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
- * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
- */
- if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
- && (sub_type == BGP_ROUTE_NORMAL)
- && (!bgp_option_check(BGP_OPT_NO_FIB))
- && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
- SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
/* If neighbor soo is configured, tag all incoming routes with
* this SoO tag and then filter out advertisements in
if (!paf->t_announce_route)
return;
- THREAD_OFF(paf->t_announce_route);
+ EVENT_OFF(paf->t_announce_route);
}
/*
* Callback that is invoked when the route announcement timer for a
* peer_af expires.
*/
-static void bgp_announce_route_timer_expired(struct thread *t)
+static void bgp_announce_route_timer_expired(struct event *t)
{
struct peer_af *paf;
struct peer *peer;
- paf = THREAD_ARG(t);
+ paf = EVENT_ARG(t);
peer = paf->peer;
if (!peer_established(peer))
* multiple peers and the announcement doesn't happen in the
* vty context.
*/
- thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
- (subgrp->peer_count == 1)
- ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
- : BGP_ANNOUNCE_ROUTE_DELAY_MS,
- &paf->t_announce_route);
+ event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
+ (subgrp->peer_count == 1)
+ ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
+ : BGP_ANNOUNCE_ROUTE_DELAY_MS,
+ &paf->t_announce_route);
}
/*
* Without splitting the full job into several part,
* vtysh waits for the job to finish before responding to a BGP command
*/
-static void bgp_soft_reconfig_table_task(struct thread *thread)
+static void bgp_soft_reconfig_table_task(struct event *thread)
{
uint32_t iter, max_iter;
struct bgp_dest *dest;
struct prefix_rd *prd;
struct listnode *node, *nnode;
- table = THREAD_ARG(thread);
+ table = EVENT_ARG(thread);
prd = NULL;
max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
*/
if (dest || table->soft_reconfig_init) {
table->soft_reconfig_init = false;
- thread_add_event(bm->master, bgp_soft_reconfig_table_task,
- table, 0, &table->soft_reconfig_thread);
+ event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
+ 0, &table->soft_reconfig_thread);
return;
}
/* we're done, clean up the background iteration context info and
list_delete(&ntable->soft_reconfig_peers);
bgp_soft_reconfig_table_flag(ntable, false);
- THREAD_OFF(ntable->soft_reconfig_thread);
+ EVENT_OFF(ntable->soft_reconfig_thread);
}
}
bgp_soft_reconfig_table_flag(table, true);
if (!table->soft_reconfig_thread)
- thread_add_event(bm->master,
- bgp_soft_reconfig_table_task, table, 0,
- &table->soft_reconfig_thread);
+ event_add_event(bm->master,
+ bgp_soft_reconfig_table_task, table, 0,
+ &table->soft_reconfig_thread);
/* Cancel bgp_announce_route_timer_expired threads.
* bgp_announce_route_timer_expired threads have been scheduled
* to announce routes as soon as the soft_reconfigure process
/* Unlock aggregate address configuration. */
bgp_dest_set_bgp_aggregate_info(dest, NULL);
- if (aggregate->community)
- community_free(&aggregate->community);
-
- if (aggregate->community_hash) {
- /* Delete all communities in the hash.
- */
- hash_clean(aggregate->community_hash,
- bgp_aggr_community_remove);
- /* Free up the community_hash.
- */
- hash_free(aggregate->community_hash);
- }
-
- if (aggregate->ecommunity)
- ecommunity_free(&aggregate->ecommunity);
-
- if (aggregate->ecommunity_hash) {
- /* Delete all ecommunities in the hash.
- */
- hash_clean(aggregate->ecommunity_hash,
- bgp_aggr_ecommunity_remove);
- /* Free up the ecommunity_hash.
- */
- hash_free(aggregate->ecommunity_hash);
- }
-
- if (aggregate->lcommunity)
- lcommunity_free(&aggregate->lcommunity);
-
- if (aggregate->lcommunity_hash) {
- /* Delete all lcommunities in the hash.
- */
- hash_clean(aggregate->lcommunity_hash,
- bgp_aggr_lcommunity_remove);
- /* Free up the lcommunity_hash.
- */
- hash_free(aggregate->lcommunity_hash);
- }
-
- if (aggregate->aspath)
- aspath_free(aggregate->aspath);
-
- if (aggregate->aspath_hash) {
- /* Delete all as-paths in the hash.
- */
- hash_clean(aggregate->aspath_hash,
- bgp_aggr_aspath_remove);
- /* Free up the aspath_hash.
- */
- hash_free(aggregate->aspath_hash);
- }
-
- bgp_aggregate_free(aggregate);
+ bgp_free_aggregate_info(aggregate);
bgp_dest_unlock_node(dest);
bgp_dest_unlock_node(dest);
match_med != NULL, suppress_map);
}
+void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
+{
+ if (aggregate->community)
+ community_free(&aggregate->community);
+
+ hash_clean_and_free(&aggregate->community_hash,
+ bgp_aggr_community_remove);
+
+ if (aggregate->ecommunity)
+ ecommunity_free(&aggregate->ecommunity);
+
+ hash_clean_and_free(&aggregate->ecommunity_hash,
+ bgp_aggr_ecommunity_remove);
+
+ if (aggregate->lcommunity)
+ lcommunity_free(&aggregate->lcommunity);
+
+ hash_clean_and_free(&aggregate->lcommunity_hash,
+ bgp_aggr_lcommunity_remove);
+
+ if (aggregate->aspath)
+ aspath_free(aggregate->aspath);
+
+ hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
+
+ bgp_aggregate_free(aggregate);
+}
+
DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
"[no] aggregate-address X:X::X:X/M$prefix [{"
"as-set$as_set_s"
if (path->peer->t_gr_restart &&
CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
unsigned long gr_remaining =
- thread_timer_remain_second(path->peer->t_gr_restart);
+ event_timer_remain_second(path->peer->t_gr_restart);
if (json_paths) {
json_object_int_add(json_path,
bgp_attr_get_community(attr) &&
community_include(bgp_attr_get_community(attr),
COMMUNITY_LLGR_STALE)) {
- unsigned long llgr_remaining = thread_timer_remain_second(
+ unsigned long llgr_remaining = event_timer_remain_second(
path->peer->t_llgr_stale[afi][safi]);
if (json_paths) {
vty_out(vty, ",\"%pFX\": ", dest_p);
}
+ /* This is used for 'json detail' vty keywords.
+ *
+ * In plain 'json' the per-prefix header is encoded
+ * as a standalone dictionary in the first json_paths
+ * array element:
+ * "<prefix>": [{header}, {path-1}, {path-N}]
+ * (which is confusing and borderline broken)
+ *
+ * For 'json detail' this changes the value
+ * of each prefix-key to be a dictionary where each
+ * header item has its own key, and json_paths is
+ * tucked under the "paths" key:
+ * "<prefix>": {
+ * "<header-key-1>": <header-val-1>,
+ * "<header-key-N>": <header-val-N>,
+ * "paths": [{path-1}, {path-N}]
+ * }
+ */
if (json_detail_header && json_paths != NULL) {
const struct prefix_rd *prd;
+ /* Start per-prefix dictionary */
vty_out(vty, "{\n");
prd = bgp_rd_from_dest(dest, safi);
*/
vty_json_no_pretty(vty, json_paths);
+ /* End per-prefix dictionary */
if (json_detail_header_used)
vty_out(vty, "} ");
}
}
-static void bgp_table_stats_walker(struct thread *t)
+static void bgp_table_stats_walker(struct event *t)
{
struct bgp_dest *dest, *ndest;
struct bgp_dest *top;
- struct bgp_table_stats *ts = THREAD_ARG(t);
+ struct bgp_table_stats *ts = EVENT_ARG(t);
unsigned int space = 0;
if (!(top = bgp_table_top(ts->table)))
memset(&ts, 0, sizeof(ts));
ts.table = bgp->rib[afi][safi];
- thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
+ event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
for (i = 0; i < BGP_STATS_MAX; i++) {
if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
}
}
-static void bgp_peer_count_walker(struct thread *t)
+static void bgp_peer_count_walker(struct event *t)
{
struct bgp_dest *rn, *rm;
const struct bgp_table *table;
- struct peer_pcounts *pc = THREAD_ARG(t);
+ struct peer_pcounts *pc = EVENT_ARG(t);
if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
|| pc->safi == SAFI_EVPN) {
* stats for the thread-walk (i.e. ensure this can't be blamed on
* on just vty_read()).
*/
- thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
+ event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
if (use_json) {
json_object_string_add(json, "prefixCountsFor", peer->host);
} export;
struct {
- struct thread *timer;
+ struct event *timer;
void *hme; /* encap monitor, if this is a VPN route */
struct prefix_rd
rd; /* import: route's route-distinguisher */
extern void bgp_route_init(void);
extern void bgp_route_finish(void);
extern void bgp_cleanup_routes(struct bgp *);
+extern void bgp_free_aggregate_info(struct bgp_aggregate *aggregate);
extern void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi,
bool force);
extern void bgp_stop_announce_route_timer(struct peer_af *paf);
vpn_policy_routemap_event(rmap_name);
}
-void bgp_route_map_update_timer(struct thread *thread)
+void bgp_route_map_update_timer(struct event *thread)
{
route_map_walk_update_list(bgp_route_map_process_update_cb);
}
/* If new update is received before the current timer timed out,
* turn it off and start a new timer.
*/
- THREAD_OFF(bm->t_rmap_update);
+ EVENT_OFF(bm->t_rmap_update);
/* rmap_update_timer of 0 means don't do route updates */
if (bm->rmap_update_timer) {
- thread_add_timer(bm->master, bgp_route_map_update_timer,
- NULL, bm->rmap_update_timer,
- &bm->t_rmap_update);
+ event_add_timer(bm->master, bgp_route_map_update_timer, NULL,
+ bm->rmap_update_timer, &bm->t_rmap_update);
/* Signal the groups that a route-map update event has
* started */
#include "command.h"
#include "linklist.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "northbound_cli.h"
#include "lib/network.h"
-#include "lib/thread.h"
#include "rtrlib/rtrlib.h"
#include "hook.h"
#include "libfrr.h"
#define RETRY_INTERVAL_DEFAULT 600
#define BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT 3
-static struct thread *t_rpki_sync;
+static struct event *t_rpki_sync;
#define RPKI_DEBUG(...) \
if (rpki_debug) { \
safi_t safi;
};
-static void rpki_revalidate_prefix(struct thread *thread)
+static void rpki_revalidate_prefix(struct event *thread)
{
- struct rpki_revalidate_prefix *rrp = THREAD_ARG(thread);
+ struct rpki_revalidate_prefix *rrp = EVENT_ARG(thread);
struct bgp_dest *match, *node;
match = bgp_table_subtree_lookup(rrp->bgp->rib[rrp->afi][rrp->safi],
XFREE(MTYPE_BGP_RPKI_REVALIDATE, rrp);
}
-static void bgpd_sync_callback(struct thread *thread)
+static void bgpd_sync_callback(struct event *thread)
{
struct bgp *bgp;
struct listnode *node;
struct prefix prefix;
struct pfx_record rec;
- thread_add_read(bm->master, bgpd_sync_callback, NULL,
- rpki_sync_socket_bgpd, NULL);
+ event_add_read(bm->master, bgpd_sync_callback, NULL,
+ rpki_sync_socket_bgpd, NULL);
if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) {
while (read(rpki_sync_socket_bgpd, &rec,
rrp->prefix = prefix;
rrp->afi = afi;
rrp->safi = safi;
- thread_add_event(bm->master, rpki_revalidate_prefix,
- rrp, 0, &bgp->t_revalidate[afi][safi]);
+ event_add_event(bm->master, rpki_revalidate_prefix, rrp,
+ 0, &bgp->t_revalidate[afi][safi]);
}
}
}
struct peer *peer;
};
-static void bgp_rpki_revalidate_peer(struct thread *thread)
+static void bgp_rpki_revalidate_peer(struct event *thread)
{
- struct rpki_revalidate_peer *rvp = THREAD_ARG(thread);
+ struct rpki_revalidate_peer *rvp = EVENT_ARG(thread);
/*
* Here's the expensive bit of gnomish deviousness
rvp->afi = afi;
rvp->safi = safi;
- thread_add_event(
+ event_add_event(
bm->master, bgp_rpki_revalidate_peer,
rvp, 0,
&peer->t_revalidate_all[afi][safi]);
}
- thread_add_read(bm->master, bgpd_sync_callback, NULL,
- rpki_sync_socket_bgpd, NULL);
+ event_add_read(bm->master, bgpd_sync_callback, NULL,
+ rpki_sync_socket_bgpd, NULL);
return;
}
-static int bgp_rpki_init(struct thread_master *master)
+static int bgp_rpki_init(struct event_loop *master)
{
rpki_debug = false;
rtr_is_running = false;
return 0;
}
-static void sync_expired(struct thread *thread)
+static void sync_expired(struct event *thread)
{
if (!rtr_mgr_conf_in_sync(rtr_config)) {
RPKI_DEBUG("rtr_mgr is not synced, retrying.");
- thread_add_timer(bm->master, sync_expired, NULL,
- BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT,
- &t_rpki_sync);
+ event_add_timer(bm->master, sync_expired, NULL,
+ BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT,
+ &t_rpki_sync);
return;
}
return ERROR;
}
- thread_add_timer(bm->master, sync_expired, NULL, 0, &t_rpki_sync);
+ event_add_timer(bm->master, sync_expired, NULL, 0, &t_rpki_sync);
XFREE(MTYPE_BGP_RPKI_CACHE_GROUP, groups);
{
rtr_is_stopping = true;
if (is_running()) {
- THREAD_OFF(t_rpki_sync);
+ EVENT_OFF(t_rpki_sync);
rtr_mgr_stop(rtr_config);
rtr_mgr_free(rtr_config);
rtr_is_running = false;
#include "log.h"
#include "prefix.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "smux.h"
#include "filter.h"
#include "hook.h"
#include "bgpd/bgp_snmp_bgp4v2.h"
#include "bgpd/bgp_mplsvpn_snmp.h"
-static int bgp_snmp_init(struct thread_master *tm)
+static int bgp_snmp_init(struct event_loop *tm)
{
smux_init(tm);
bgp_snmp_bgp4_init(tm);
#include "log.h"
#include "prefix.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "smux.h"
#include "filter.h"
#include "hook.h"
return 0;
}
-int bgp_snmp_bgp4_init(struct thread_master *tm)
+int bgp_snmp_bgp4_init(struct event_loop *tm)
{
REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
return 0;
extern int bgpTrapEstablished(struct peer *peer);
extern int bgpTrapBackwardTransition(struct peer *peer);
-extern int bgp_snmp_bgp4_init(struct thread_master *tm);
+extern int bgp_snmp_bgp4_init(struct event_loop *tm);
#endif /* _FRR_BGP_SNMP_BGP4_H_ */
#include "log.h"
#include "prefix.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "smux.h"
#include "filter.h"
#include "hook.h"
{1, 9, 1, BGP4V2_NLRI_PATH_ATTR_UNKNOWN, 2, 16}},
};
-int bgp_snmp_bgp4v2_init(struct thread_master *tm)
+int bgp_snmp_bgp4v2_init(struct event_loop *tm)
{
REGISTER_MIB("mibII/bgpv2", bgpv2_variables, variable, bgpv2_oid);
return 0;
#define BGP4V2_ESTABLISHED_NOTIFICATION 1
#define BGP4V2_BACKWARD_TRANSITION_NOTIFICATION 2
-extern int bgp_snmp_bgp4v2_init(struct thread_master *tm);
+extern int bgp_snmp_bgp4v2_init(struct event_loop *tm);
#endif /* _FRR_BGP_SNMP_BGP4V2_H_ */
/* soft_reconfig_table in progress */
bool soft_reconfig_init;
- struct thread *soft_reconfig_thread;
+ struct event *soft_reconfig_thread;
/* list of peers on which soft_reconfig_table has to run */
struct list *soft_reconfig_peers;
#include <zebra.h>
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "stream.h"
#include "command.h"
static void sync_delete(struct update_subgroup *subgrp)
{
XFREE(MTYPE_BGP_SYNCHRONISE, subgrp->sync);
- if (subgrp->hash) {
- hash_clean(subgrp->hash,
- (void (*)(void *))bgp_advertise_attr_free);
- hash_free(subgrp->hash);
- }
- subgrp->hash = NULL;
+ hash_clean_and_free(&subgrp->hash,
+ (void (*)(void *))bgp_advertise_attr_free);
+
if (subgrp->work)
stream_free(subgrp->work);
subgrp->work = NULL;
if (subgrp->update_group)
UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted);
- THREAD_OFF(subgrp->t_merge_check);
- THREAD_OFF(subgrp->t_coalesce);
+ EVENT_OFF(subgrp->t_merge_check);
+ EVENT_OFF(subgrp->t_coalesce);
bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp));
subgroup_clear_table(subgrp);
/*
* update_subgroup_merge_check_thread_cb
*/
-static void update_subgroup_merge_check_thread_cb(struct thread *thread)
+static void update_subgroup_merge_check_thread_cb(struct event *thread)
{
struct update_subgroup *subgrp;
- subgrp = THREAD_ARG(thread);
+ subgrp = EVENT_ARG(thread);
subgrp->t_merge_check = NULL;
return false;
subgrp->t_merge_check = NULL;
- thread_add_timer_msec(bm->master, update_subgroup_merge_check_thread_cb,
- subgrp, 0, &subgrp->t_merge_check);
+ event_add_timer_msec(bm->master, update_subgroup_merge_check_thread_cb,
+ subgrp, 0, &subgrp->t_merge_check);
SUBGRP_INCR_STAT(subgrp, merge_checks_triggered);
return UPDWALK_CONTINUE;
}
-void update_group_refresh_default_originate_route_map(struct thread *thread)
+void update_group_refresh_default_originate_route_map(struct event *thread)
{
struct bgp *bgp;
char reason[] = "refresh default-originate route-map";
- bgp = THREAD_ARG(thread);
+ bgp = EVENT_ARG(thread);
update_group_walk(bgp, update_group_default_originate_route_map_walkcb,
reason);
- THREAD_OFF(bgp->t_rmap_def_originate_eval);
+ EVENT_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp);
}
*/
SUBGRP_FOREACH_PEER (subgrp, paf)
if (peer_established(paf->peer))
- thread_add_timer_msec(
+ event_add_timer_msec(
bm->master, bgp_generate_updgrp_packets,
paf->peer, 0,
&paf->peer->t_generate_updgrp_packets);
/* announcement attribute hash */
struct hash *hash;
- struct thread *t_coalesce;
+ struct event *t_coalesce;
uint32_t v_coalesce;
- struct thread *t_merge_check;
+ struct event *t_merge_check;
/* table version that the subgroup has caught up to. */
uint64_t version;
extern void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx);
extern void update_group_periodic_merge(struct bgp *bgp);
extern void
-update_group_refresh_default_originate_route_map(struct thread *thread);
+update_group_refresh_default_originate_route_map(struct event *thread);
extern void update_group_start_advtimer(struct bgp *bgp);
extern void update_subgroup_inherit_info(struct update_subgroup *to,
#include "memory.h"
#include "prefix.h"
#include "hash.h"
-#include "thread.h"
+#include "frrevent.h"
#include "queue.h"
#include "routemap.h"
#include "filter.h"
update_group_af_walk(bgp, afi, safi, updgrp_show_adj_walkcb, &ctx);
}
-static void subgroup_coalesce_timer(struct thread *thread)
+static void subgroup_coalesce_timer(struct event *thread)
{
struct update_subgroup *subgrp;
struct bgp *bgp;
- subgrp = THREAD_ARG(thread);
+ subgrp = EVENT_ARG(thread);
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
zlog_debug("u%" PRIu64 ":s%" PRIu64" announcing routes upon coalesce timer expiry(%u ms)",
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
SUBGRP_FOREACH_PEER (subgrp, paf) {
peer = PAF_PEER(paf);
- THREAD_OFF(peer->t_routeadv);
+ EVENT_OFF(peer->t_routeadv);
BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
}
}
* We should wait for the coalesce timer. Arm the timer if not done.
*/
if (!subgrp->t_coalesce) {
- thread_add_timer_msec(bm->master, subgroup_coalesce_timer,
- subgrp, subgrp->v_coalesce,
- &subgrp->t_coalesce);
+ event_add_timer_msec(bm->master, subgroup_coalesce_timer,
+ subgrp, subgrp->v_coalesce,
+ &subgrp->t_coalesce);
}
}
#include <zebra.h>
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "stream.h"
#include "command.h"
#include "buffer.h"
#include "linklist.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "memory.h"
#include "lib_vty.h"
/* Cancel max-med onstartup if its on */
if (bgp->t_maxmed_onstartup) {
- THREAD_OFF(bgp->t_maxmed_onstartup);
+ EVENT_OFF(bgp->t_maxmed_onstartup);
bgp->maxmed_onstartup_over = 1;
}
* fired.
*/
if (!rmap_delay_timer && bm->t_rmap_update) {
- THREAD_OFF(bm->t_rmap_update);
- thread_execute(bm->master, bgp_route_map_update_timer,
- NULL, 0);
+ EVENT_OFF(bm->t_rmap_update);
+ event_execute(bm->master, bgp_route_map_update_timer,
+ NULL, 0);
}
return CMD_SUCCESS;
} else {
{
static char stripped[BUFSIZ];
uint32_t i = 0;
- uint32_t last_space = 0;
+ uint32_t last_space = size;
while (i < size) {
- if (*(desc + i) == 0) {
+ if (*(desc + i) == '\0') {
stripped[i] = '\0';
return stripped;
}
i++;
}
- if (last_space > size)
- stripped[size + 1] = '\0';
- else
- stripped[last_space] = '\0';
+ stripped[last_space] = '\0';
return stripped;
}
if (peer->t_gr_stale != NULL) {
json_object_int_add(json_timer,
"stalePathTimerRemaining",
- thread_timer_remain_second(
+ event_timer_remain_second(
peer->t_gr_stale));
}
json_object_int_add(
json_timer,
"selectionDeferralTimerRemaining",
- thread_timer_remain_second(
+ event_timer_remain_second(
peer->bgp->gr_info[afi][safi]
.t_select_deferral));
}
if (peer->t_gr_stale != NULL)
vty_out(vty,
" Stale Path Remaining(sec): %ld\n",
- thread_timer_remain_second(
+ event_timer_remain_second(
peer->t_gr_stale));
/* Display Configured Selection
* Deferral only when when
NULL)
vty_out(vty,
" Selection Deferral Time Remaining(sec): %ld\n",
- thread_timer_remain_second(
+ event_timer_remain_second(
peer->bgp->gr_info[afi][safi]
.t_select_deferral));
}
if (p->t_gr_restart != NULL)
json_object_int_add(
json_timer, "restartTimerRemaining",
- thread_timer_remain_second(p->t_gr_restart));
+ event_timer_remain_second(p->t_gr_restart));
json_object_object_add(json, "timers", json_timer);
} else {
p->v_gr_restart);
if (p->t_gr_restart != NULL)
vty_out(vty, " Restart Time Remaining(sec): %ld\n",
- thread_timer_remain_second(p->t_gr_restart));
+ event_timer_remain_second(p->t_gr_restart));
if (p->t_gr_restart != NULL) {
vty_out(vty, " Restart Time Remaining(sec): %ld\n",
- thread_timer_remain_second(p->t_gr_restart));
+ event_timer_remain_second(p->t_gr_restart));
}
}
}
json_neigh,
"bgpTimerConfiguredConditionalAdvertisementsSec",
bgp->condition_check_period);
- if (thread_is_scheduled(bgp->t_condition_check))
+ if (event_is_scheduled(bgp->t_condition_check))
json_object_int_add(
json_neigh,
"bgpTimerUntilConditionalAdvertisementsSec",
- thread_timer_remain_second(
+ event_timer_remain_second(
bgp->t_condition_check));
} else {
/* Administrative shutdown. */
vty_out(vty,
" Configured conditional advertisements interval is %d seconds\n",
bgp->condition_check_period);
- if (thread_is_scheduled(bgp->t_condition_check))
+ if (event_is_scheduled(bgp->t_condition_check))
vty_out(vty,
" Time until conditional advertisements begin is %lu seconds\n",
- thread_timer_remain_second(
+ event_timer_remain_second(
bgp->t_condition_check));
}
/* Capability. */
if (p->t_gr_restart)
json_object_int_add(
json_grace, "gracefulRestartTimerMsecs",
- thread_timer_remain_second(p->t_gr_restart) *
+ event_timer_remain_second(p->t_gr_restart) *
1000);
if (p->t_gr_stale)
json_object_int_add(
json_grace, "gracefulStalepathTimerMsecs",
- thread_timer_remain_second(p->t_gr_stale) *
+ event_timer_remain_second(p->t_gr_stale) *
1000);
/* more gr info in new format */
BGP_SHOW_PEER_GR_CAPABILITY(vty, p, json_grace);
if (p->t_gr_restart)
vty_out(vty,
" The remaining time of restart timer is %ld\n",
- thread_timer_remain_second(p->t_gr_restart));
+ event_timer_remain_second(p->t_gr_restart));
if (p->t_gr_stale)
vty_out(vty,
" The remaining time of stalepath timer is %ld\n",
- thread_timer_remain_second(p->t_gr_stale));
+ event_timer_remain_second(p->t_gr_stale));
/* more gr info in new format */
BGP_SHOW_PEER_GR_CAPABILITY(vty, p, NULL);
json_neigh, "reducePrefixNumFrom");
json_object_int_add(json_neigh,
"restartInTimerMsec",
- thread_timer_remain_second(
- p->t_pmax_restart)
- * 1000);
+ event_timer_remain_second(
+ p->t_pmax_restart) *
+ 1000);
} else
vty_out(vty,
" Reduce the no. of prefix from %s, will restart in %ld seconds\n",
- p->host, thread_timer_remain_second(
- p->t_pmax_restart));
+ p->host,
+ event_timer_remain_second(
+ p->t_pmax_restart));
} else {
if (use_json)
json_object_boolean_true_add(
if (p->t_start)
json_object_int_add(
json_neigh, "nextStartTimerDueInMsecs",
- thread_timer_remain_second(p->t_start) * 1000);
+ event_timer_remain_second(p->t_start) * 1000);
if (p->t_connect)
json_object_int_add(
json_neigh, "nextConnectTimerDueInMsecs",
- thread_timer_remain_second(p->t_connect)
- * 1000);
+ event_timer_remain_second(p->t_connect) * 1000);
if (p->t_routeadv) {
json_object_int_add(json_neigh, "mraiInterval",
p->v_routeadv);
json_object_int_add(
json_neigh, "mraiTimerExpireInMsecs",
- thread_timer_remain_second(p->t_routeadv)
- * 1000);
+ event_timer_remain_second(p->t_routeadv) *
+ 1000);
}
if (p->password)
json_object_int_add(json_neigh, "authenticationEnabled",
}
if (p->t_start)
vty_out(vty, "Next start timer due in %ld seconds\n",
- thread_timer_remain_second(p->t_start));
+ event_timer_remain_second(p->t_start));
if (p->t_connect)
vty_out(vty, "Next connect timer due in %ld seconds\n",
- thread_timer_remain_second(p->t_connect));
+ event_timer_remain_second(p->t_connect));
if (p->t_routeadv)
vty_out(vty,
"MRAI (interval %u) timer expires in %ld seconds\n",
p->v_routeadv,
- thread_timer_remain_second(p->t_routeadv));
+ event_timer_remain_second(p->t_routeadv));
if (p->password)
vty_out(vty, "Peer Authentication Enabled\n");
DEFINE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp));
-static struct thread *t_bgp_cfg;
+static struct event *t_bgp_cfg;
bool bgp_config_inprocess(void)
{
- return thread_is_scheduled(t_bgp_cfg);
+ return event_is_scheduled(t_bgp_cfg);
}
-static void bgp_config_finish(struct thread *t)
+static void bgp_config_finish(struct event *t)
{
struct listnode *node;
struct bgp *bgp;
static void bgp_config_start(void)
{
#define BGP_PRE_CONFIG_MAX_WAIT_SECONDS 600
- THREAD_OFF(t_bgp_cfg);
- thread_add_timer(bm->master, bgp_config_finish, NULL,
- BGP_PRE_CONFIG_MAX_WAIT_SECONDS, &t_bgp_cfg);
+ EVENT_OFF(t_bgp_cfg);
+ event_add_timer(bm->master, bgp_config_finish, NULL,
+ BGP_PRE_CONFIG_MAX_WAIT_SECONDS, &t_bgp_cfg);
}
/* When we receive a hook the configuration is read,
{
#define BGP_POST_CONFIG_DELAY_SECONDS 1
uint32_t bgp_post_config_delay =
- thread_is_scheduled(bm->t_rmap_update)
- ? thread_timer_remain_second(bm->t_rmap_update)
+ event_is_scheduled(bm->t_rmap_update)
+ ? event_timer_remain_second(bm->t_rmap_update)
: BGP_POST_CONFIG_DELAY_SECONDS;
/* If BGP config processing thread isn't running, then
if (!bgp_config_inprocess())
return;
- THREAD_OFF(t_bgp_cfg);
+ EVENT_OFF(t_bgp_cfg);
/* Start a new timer to make sure we don't send EoR
* before route-maps are processed.
*/
- thread_add_timer(bm->master, bgp_config_finish, NULL,
- bgp_post_config_delay, &t_bgp_cfg);
+ event_add_timer(bm->master, bgp_config_finish, NULL,
+ bgp_post_config_delay, &t_bgp_cfg);
}
static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
#include "sockunion.h"
#include "zclient.h"
#include "routemap.h"
-#include "thread.h"
+#include "frrevent.h"
#include "queue.h"
#include "memory.h"
#include "lib/json.h"
peer->bgp->vrf_id);
}
+ /* Handle peerings via loopbacks. For instance, peer between
+ * 127.0.0.1 and 127.0.0.2. In short, allow peering with self
+ * via 127.0.0.0/8.
+ */
+ if (!ifp && cmd_allow_reserved_ranges_get())
+ ifp = if_get_vrf_loopback(peer->bgp->vrf_id);
+
if (!ifp) {
/*
* BGP views do not currently get proper data
return false;
}
-static struct thread *bgp_tm_thread_connect;
+static struct event *bgp_tm_thread_connect;
static bool bgp_tm_status_connected;
static bool bgp_tm_chunk_obtained;
#define BGP_FLOWSPEC_TABLE_CHUNK 100000
static uint32_t bgp_tm_min, bgp_tm_max, bgp_tm_chunk_size;
struct bgp *bgp_tm_bgp;
-static void bgp_zebra_tm_connect(struct thread *t)
+static void bgp_zebra_tm_connect(struct event *t)
{
struct zclient *zclient;
int delay = 10, ret = 0;
- zclient = THREAD_ARG(t);
+ zclient = EVENT_ARG(t);
if (bgp_tm_status_connected && zclient->sock > 0)
delay = 60;
else {
}
}
}
- thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
- &bgp_tm_thread_connect);
+ event_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
+ &bgp_tm_thread_connect);
}
bool bgp_zebra_tm_chunk_obtained(void)
bgp_tm_min = bgp_tm_max = 0;
bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK;
bgp_tm_bgp = bgp;
- thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
- &bgp_tm_thread_connect);
+ event_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
+ &bgp_tm_thread_connect);
}
int bgp_zebra_get_table_range(uint32_t chunk_size,
uint32_t bos = 0;
uint32_t exp = 0;
+ /*
+ * BGP is installing this route and bgp has been configured
+ * to suppress announcements until the route has been installed
+ * let's set the fact that we expect this route to be installed
+ */
+ if (BGP_SUPPRESS_FIB_ENABLED(bgp))
+ SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
+
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
struct zapi_route api;
struct peer *peer;
+ /*
+ * If we are withdrawing the route, we don't need to have this
+ * flag set. So unset it.
+ */
+ UNSET_FLAG(info->net->flags, BGP_NODE_FIB_INSTALL_PENDING);
+
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
hook_register_prio(if_del, 0, bgp_if_delete_hook);
}
-void bgp_zebra_init(struct thread_master *master, unsigned short instance)
+void bgp_zebra_init(struct event_loop *master, unsigned short instance)
{
zclient_num_connects = 0;
/* Default weight for next hop, if doing weighted ECMP. */
#define BGP_ZEBRA_DEFAULT_NHOP_WEIGHT 1
-extern void bgp_zebra_init(struct thread_master *master,
- unsigned short instance);
+extern void bgp_zebra_init(struct event_loop *master, unsigned short instance);
extern void bgp_if_init(void);
extern void bgp_zebra_init_tm_connect(struct bgp *bgp);
extern uint32_t bgp_zebra_tm_get_id(void);
#include <zebra.h>
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "stream.h"
#include "ringbuf.h"
bgp_timer_set(peer);
bgp_reads_off(peer);
bgp_writes_off(peer);
- thread_cancel_event_ready(bm->master, peer);
+ event_cancel_event_ready(bm->master, peer);
FOREACH_AFI_SAFI (afi, safi)
- THREAD_OFF(peer->t_revalidate_all[afi][safi]);
+ EVENT_OFF(peer->t_revalidate_all[afi][safi]);
assert(!peer->t_write);
assert(!peer->t_read);
BGP_EVENT_FLUSH(peer);
peer_dst->v_delayopen = peer_src->v_delayopen;
/* password apply */
- if (peer_src->password && !peer_dst->password)
+ if (peer_src->password) {
+ XFREE(MTYPE_PEER_PASSWORD, peer_dst->password);
peer_dst->password =
XSTRDUP(MTYPE_PEER_PASSWORD, peer_src->password);
+ }
FOREACH_AFI_SAFI (afi, safi) {
peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
FOREACH_AFI_SAFI_NSF (afi, safi) {
peer->nsf[afi][safi] = 0;
- THREAD_OFF(peer->t_llgr_stale[afi][safi]);
+ EVENT_OFF(peer->t_llgr_stale[afi][safi]);
}
if (peer->t_gr_restart) {
- THREAD_OFF(peer->t_gr_restart);
+ EVENT_OFF(peer->t_gr_restart);
if (bgp_debug_neighbor_events(peer))
zlog_debug("%pBP graceful restart timer stopped", peer);
}
if (peer->t_gr_stale) {
- THREAD_OFF(peer->t_gr_stale);
+ EVENT_OFF(peer->t_gr_stale);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP graceful restart stalepath timer stopped",
bgp_keepalives_off(peer);
bgp_reads_off(peer);
bgp_writes_off(peer);
- thread_cancel_event_ready(bm->master, peer);
+ event_cancel_event_ready(bm->master, peer);
FOREACH_AFI_SAFI (afi, safi)
- THREAD_OFF(peer->t_revalidate_all[afi][safi]);
+ EVENT_OFF(peer->t_revalidate_all[afi][safi]);
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON));
return 0;
}
-static void bgp_startup_timer_expire(struct thread *thread)
+static void bgp_startup_timer_expire(struct event *thread)
{
struct bgp *bgp;
- bgp = THREAD_ARG(thread);
+ bgp = EVENT_ARG(thread);
bgp->t_startup = NULL;
}
if (name)
bgp->name = XSTRDUP(MTYPE_BGP, name);
- thread_add_timer(bm->master, bgp_startup_timer_expire, bgp,
- bgp->restart_time, &bgp->t_startup);
+ event_add_timer(bm->master, bgp_startup_timer_expire, bgp,
+ bgp->restart_time, &bgp->t_startup);
/* printable name we can use in debug messages */
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
/* Stop timers. */
if (bgp->t_rmap_def_originate_eval) {
- THREAD_OFF(bgp->t_rmap_def_originate_eval);
+ EVENT_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp); /* TODO - This timer is started with a lock -
why? */
}
hook_call(bgp_inst_delete, bgp);
FOREACH_AFI_SAFI (afi, safi)
- THREAD_OFF(bgp->t_revalidate[afi][safi]);
+ EVENT_OFF(bgp->t_revalidate[afi][safi]);
- THREAD_OFF(bgp->t_condition_check);
- THREAD_OFF(bgp->t_startup);
- THREAD_OFF(bgp->t_maxmed_onstartup);
- THREAD_OFF(bgp->t_update_delay);
- THREAD_OFF(bgp->t_establish_wait);
+ EVENT_OFF(bgp->t_condition_check);
+ EVENT_OFF(bgp->t_startup);
+ EVENT_OFF(bgp->t_maxmed_onstartup);
+ EVENT_OFF(bgp->t_update_delay);
+ EVENT_OFF(bgp->t_establish_wait);
/* Set flag indicating bgp instance delete in progress */
SET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS);
/* Delete the graceful restart info */
FOREACH_AFI_SAFI (afi, safi) {
- struct thread *t;
+ struct event *t;
gr_info = &bgp->gr_info[afi][safi];
if (!gr_info)
continue;
t = gr_info->t_select_deferral;
if (t) {
- void *info = THREAD_ARG(t);
+ void *info = EVENT_ARG(t);
XFREE(MTYPE_TMP, info);
}
- THREAD_OFF(gr_info->t_select_deferral);
+ EVENT_OFF(gr_info->t_select_deferral);
t = gr_info->t_route_select;
if (t) {
- void *info = THREAD_ARG(t);
+ void *info = EVENT_ARG(t);
XFREE(MTYPE_TMP, info);
}
- THREAD_OFF(gr_info->t_route_select);
+ EVENT_OFF(gr_info->t_route_select);
}
if (BGP_DEBUG(zebra, ZEBRA)) {
/* Stop timers. */
if (bgp->t_rmap_def_originate_eval) {
- THREAD_OFF(bgp->t_rmap_def_originate_eval);
+ EVENT_OFF(bgp->t_rmap_def_originate_eval);
bgp_unlock(bgp); /* TODO - This timer is started with a lock -
why? */
}
#ifdef ENABLE_BGP_VNC
rfapi_delete(bgp);
#endif
+
+ /* Free memory allocated with aggregate address configuration. */
+ FOREACH_AFI_SAFI (afi, safi) {
+ struct bgp_aggregate *aggregate = NULL;
+
+ for (struct bgp_dest *dest =
+ bgp_table_top(bgp->aggregate[afi][safi]);
+ dest; dest = bgp_route_next(dest)) {
+ aggregate = bgp_dest_get_bgp_aggregate_info(dest);
+ if (aggregate == NULL)
+ continue;
+
+ bgp_dest_set_bgp_aggregate_info(dest, NULL);
+ bgp_free_aggregate_info(aggregate);
+ }
+ }
+
bgp_cleanup_routes(bgp);
for (afi = 0; afi < AFI_MAX; ++afi) {
if (bgp->process_queue)
work_queue_free_and_null(&bgp->process_queue);
- thread_master_free_unused(bm->master);
+ event_master_free_unused(bm->master);
bgp_unlock(bgp); /* initial reference */
return 0;
UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
if (peer->t_pmax_restart) {
- THREAD_OFF(peer->t_pmax_restart);
+ EVENT_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP Maximum-prefix restart timer canceled",
return;
if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) ||
- CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV)) {
- if (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_SM_ADV) &&
- (CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_RM_RCV) ||
- CHECK_FLAG(peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
- peer_clear_soft(peer, afi, safi,
- BGP_CLEAR_SOFT_IN_ORF_PREFIX);
- else
- bgp_route_refresh_send(
- peer, afi, safi, 0, 0, 0,
- BGP_ROUTE_REFRESH_NORMAL);
- }
+ CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
+ bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
+ BGP_ROUTE_REFRESH_NORMAL);
}
}
/* If we touch prefix-list, we need to process
* new updates. This is important for ORF to
- * work correctly as well.
+ * work correctly.
*/
- if (peer->afc_nego[afi][safi])
- peer_on_policy_change(peer, afi, safi,
- 0);
+ if (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_SM_ADV) &&
+ (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_RM_RCV) ||
+ CHECK_FLAG(
+ peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
+ peer_clear_soft(
+ peer, afi, safi,
+ BGP_CLEAR_SOFT_IN_ORF_PREFIX);
}
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
if (peer->t_pmax_restart) {
- THREAD_OFF(peer->t_pmax_restart);
+ EVENT_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%pBP Maximum-prefix restart timer cancelled",
return buf;
}
-void bgp_master_init(struct thread_master *master, const int buffer_size,
+void bgp_master_init(struct event_loop *master, const int buffer_size,
struct list *addresses)
{
qobj_init();
if (bm->listen_sockets)
list_delete(&bm->listen_sockets);
- THREAD_OFF(bm->t_rmap_update);
+ EVENT_OFF(bm->t_rmap_update);
bgp_mac_finish();
}
struct list *bgp;
/* BGP thread master. */
- struct thread_master *master;
+ struct event_loop *master;
/* Listening sockets */
struct list *listen_sockets;
uint64_t subgrp_idspace;
/* timer to dampen route map changes */
- struct thread *t_rmap_update; /* Handle route map updates */
+ struct event *t_rmap_update; /* Handle route map updates */
uint32_t rmap_update_timer; /* Route map update timer */
#define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
/* Count of EOR received */
uint32_t eor_received;
/* Deferral Timer */
- struct thread *t_select_deferral;
+ struct event *t_select_deferral;
/* Routes Deferred */
uint32_t gr_deferred;
/* Best route select */
- struct thread *t_route_select;
+ struct event *t_route_select;
/* AFI, SAFI enabled */
bool af_enabled[AFI_MAX][SAFI_MAX];
/* Route update completed */
struct as_confed *confed_peers;
int confed_peers_cnt;
- struct thread
- *t_startup; /* start-up timer on only once at the beginning */
+ /* start-up timer on only once at the beginning */
+ struct event *t_startup;
uint32_t v_maxmed_onstartup; /* Duration of max-med on start-up */
#define BGP_MAXMED_ONSTARTUP_UNCONFIGURED 0 /* 0 means off, its the default */
uint32_t maxmed_onstartup_value; /* Max-med value when active on
start-up */
- struct thread
- *t_maxmed_onstartup; /* non-null when max-med onstartup is on */
+
+ /* non-null when max-med onstartup is on */
+ struct event *t_maxmed_onstartup;
uint8_t maxmed_onstartup_over; /* Flag to make it effective only once */
bool v_maxmed_admin; /* true/false if max-med administrative is on/off
uint32_t maxmed_value; /* Max-med value when its active */
/* BGP update delay on startup */
- struct thread *t_update_delay;
- struct thread *t_establish_wait;
- struct thread *t_revalidate[AFI_MAX][SAFI_MAX];
+ struct event *t_update_delay;
+ struct event *t_establish_wait;
+ struct event *t_revalidate[AFI_MAX][SAFI_MAX];
uint8_t update_delay_over;
uint8_t main_zebra_update_hold;
struct hash *pbr_action_hash;
/* timer to re-evaluate neighbor default-originate route-maps */
- struct thread *t_rmap_def_originate_eval;
+ struct event *t_rmap_def_originate_eval;
#define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5
/* BGP distance configuration. */
/* BGP Conditional advertisement */
uint32_t condition_check_period;
uint32_t condition_filter_count;
- struct thread *t_condition_check;
+ struct event *t_condition_check;
/* BGP VPN SRv6 backend */
bool srv6_enabled;
/*
* Trigger timer for bgp_announce_route().
*/
- struct thread *t_announce_route;
+ struct event *t_announce_route;
afi_t afi;
safi_t safi;
_Atomic uint32_t v_gr_restart;
/* Threads. */
- struct thread *t_read;
- struct thread *t_write;
- struct thread *t_start;
- struct thread *t_connect_check_r;
- struct thread *t_connect_check_w;
- struct thread *t_connect;
- struct thread *t_holdtime;
- struct thread *t_routeadv;
- struct thread *t_delayopen;
- struct thread *t_pmax_restart;
- struct thread *t_gr_restart;
- struct thread *t_gr_stale;
- struct thread *t_llgr_stale[AFI_MAX][SAFI_MAX];
- struct thread *t_revalidate_all[AFI_MAX][SAFI_MAX];
- struct thread *t_generate_updgrp_packets;
- struct thread *t_process_packet;
- struct thread *t_process_packet_error;
- struct thread *t_refresh_stalepath;
+ struct event *t_read;
+ struct event *t_write;
+ struct event *t_start;
+ struct event *t_connect_check_r;
+ struct event *t_connect_check_w;
+ struct event *t_connect;
+ struct event *t_holdtime;
+ struct event *t_routeadv;
+ struct event *t_delayopen;
+ struct event *t_pmax_restart;
+ struct event *t_gr_restart;
+ struct event *t_gr_stale;
+ struct event *t_llgr_stale[AFI_MAX][SAFI_MAX];
+ struct event *t_revalidate_all[AFI_MAX][SAFI_MAX];
+ struct event *t_generate_updgrp_packets;
+ struct event *t_process_packet;
+ struct event *t_process_packet_error;
+ struct event *t_refresh_stalepath;
/* Thread flags. */
_Atomic uint32_t thread_flags;
extern int bgp_config_write(struct vty *);
-extern void bgp_master_init(struct thread_master *master, const int buffer_size,
+extern void bgp_master_init(struct event_loop *master, const int buffer_size,
struct list *addresses);
extern void bgp_init(unsigned short instance);
extern void peer_tx_shutdown_message_set(struct peer *, const char *msg);
extern void peer_tx_shutdown_message_unset(struct peer *);
-extern void bgp_route_map_update_timer(struct thread *thread);
+extern void bgp_route_map_update_timer(struct event *thread);
extern const char *bgp_get_name_by_role(uint8_t role);
extern enum asnotation_mode bgp_get_asnotation(struct bgp *bgp);
* return value:
* rfp_start_val rfp returned value passed on rfp_stop and other rfapi calls
--------------------------------------------*/
-extern void *rfp_start(struct thread_master *master,
- struct rfapi_rfp_cfg **cfgp,
+extern void *rfp_start(struct event_loop *master, struct rfapi_rfp_cfg **cfgp,
struct rfapi_rfp_cb_methods **cbmp);
/*------------------------------------------
#include "bgpd/bgp_nexthop.h"
extern void rfapi_init(void);
-extern void vnc_zebra_init(struct thread_master *master);
+extern void vnc_zebra_init(struct event_loop *master);
extern void vnc_zebra_destroy(void);
extern void rfapi_delete(struct bgp *);
#include "lib/memory.h"
#include "lib/log.h"
#include "lib/skiplist.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/stream.h"
#include "lib/lib_errors.h"
struct agg_node *rn;
int holddown_count = 0;
- int local_count = 0;
int imported_count = 0;
int remote_count = 0;
++holddown_count;
} else {
- if (RFAPI_LOCAL_BI(bpi)) {
- ++local_count;
- } else {
+ if (!RFAPI_LOCAL_BI(bpi)) {
if (RFAPI_DIRECT_IMPORT_BI(
bpi)) {
++imported_count;
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
&& bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(bpi->extra->vnc.import.timer);
+ EVENT_ARG(bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
next = bpi->next;
/*
* Timer callback for withdraw
*/
-static void rfapiWithdrawTimerVPN(struct thread *t)
+static void rfapiWithdrawTimerVPN(struct event *t)
{
- struct rfapi_withdraw *wcb = THREAD_ARG(t);
+ struct rfapi_withdraw *wcb = EVENT_ARG(t);
struct bgp_path_info *bpi = wcb->info;
struct bgp *bgp = bgp_get_default();
const struct prefix *p;
return 0;
}
-static void rfapiWithdrawTimerEncap(struct thread *t)
+static void rfapiWithdrawTimerEncap(struct event *t)
{
- struct rfapi_withdraw *wcb = THREAD_ARG(t);
+ struct rfapi_withdraw *wcb = EVENT_ARG(t);
struct bgp_path_info *bpi = wcb->info;
int was_first_route = 0;
struct rfapi_monitor_encap *em;
rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table,
struct agg_node *rn, struct bgp_path_info *bpi,
afi_t afi, safi_t safi,
- void (*timer_service_func)(struct thread *))
+ void (*timer_service_func)(struct event *))
{
uint32_t lifetime;
struct rfapi_withdraw *wcb;
if (lifetime > UINT32_MAX / 1001) {
/* sub-optimal case, but will probably never happen */
bpi->extra->vnc.import.timer = NULL;
- thread_add_timer(bm->master, timer_service_func, wcb, lifetime,
- &bpi->extra->vnc.import.timer);
+ event_add_timer(bm->master, timer_service_func, wcb, lifetime,
+ &bpi->extra->vnc.import.timer);
} else {
static uint32_t jitter;
uint32_t lifetime_msec;
lifetime_msec = (lifetime * 1000) + jitter;
bpi->extra->vnc.import.timer = NULL;
- thread_add_timer_msec(bm->master, timer_service_func, wcb,
- lifetime_msec,
- &bpi->extra->vnc.import.timer);
+ event_add_timer_msec(bm->master, timer_service_func, wcb,
+ lifetime_msec,
+ &bpi->extra->vnc.import.timer);
}
/* re-sort route list (BGP_PATH_REMOVED routes are last) */
struct agg_node *rn, struct bgp_path_info *bpi)
{
struct rfapi_withdraw *wcb;
- struct thread t;
+ struct event t;
/*
* pretend we're an expiring timer
*/
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
&& bpi->extra->vnc.import.timer) {
- struct rfapi_withdraw *wcb = THREAD_ARG(
+ struct rfapi_withdraw *wcb = EVENT_ARG(
bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(
- bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
if (action == FIF_ACTION_UPDATE) {
* bpi
*/
struct rfapi_withdraw *wcb;
- struct thread t;
+ struct event t;
/*
* pretend we're an expiring timer
__func__);
if (bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(bpi->extra->vnc.import.timer);
+ EVENT_ARG(bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
rfapiExpireEncapNow(import_table, rn, bpi);
}
int lockoffset)
{
struct rfapi_withdraw *wcb;
- struct thread t;
+ struct event t;
/*
* pretend we're an expiring timer
*/
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
&& bpi->extra->vnc.import.timer) {
- struct rfapi_withdraw *wcb = THREAD_ARG(
+ struct rfapi_withdraw *wcb = EVENT_ARG(
bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(
- bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
import_table->holddown_count[afi] -= 1;
RFAPI_UPDATE_ITABLE_COUNT(
__func__);
if (bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(bpi->extra->vnc.import.timer);
+ EVENT_ARG(bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
rfapiExpireVpnNow(import_table, rn, bpi, 0);
}
struct agg_node *rn;
struct bgp_path_info *bpi;
struct agg_table *rt = NULL;
- void (*timer_service_func)(struct thread *) = NULL;
+ void (*timer_service_func)(struct event *) = NULL;
assert(afi == AFI_IP || afi == AFI_IP6);
continue;
if (bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(
+ EVENT_ARG(
bpi->extra->vnc
.import
.timer);
afi, 1);
XFREE(MTYPE_RFAPI_WITHDRAW,
wcb);
- THREAD_OFF(
- bpi->extra->vnc.import
- .timer);
+ EVENT_OFF(bpi->extra->vnc.import
+ .timer);
}
} else {
if (!delete_active)
#ifndef QUAGGA_HGP_RFAPI_IMPORT_H
#define QUAGGA_HGP_RFAPI_IMPORT_H
-#include "lib/thread.h"
+#include "frrevent.h"
/*
* These are per-rt-import-list
rfapiMonitorDetachImport(m);
}
- THREAD_OFF(m->timer);
+ EVENT_OFF(m->timer);
/*
* remove from rfd list
rfapiMonitorDetachImport(m);
}
- THREAD_OFF(m->timer);
+ EVENT_OFF(m->timer);
XFREE(MTYPE_RFAPI_MONITOR, m);
rn->info = NULL;
#endif
}
- THREAD_OFF(mon_eth->timer);
+ EVENT_OFF(mon_eth->timer);
/*
* remove from rfd list
bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
}
-static void rfapiMonitorTimerExpire(struct thread *t)
+static void rfapiMonitorTimerExpire(struct event *t)
{
- struct rfapi_monitor_vpn *m = THREAD_ARG(t);
+ struct rfapi_monitor_vpn *m = EVENT_ARG(t);
/* forget reference to thread, it's gone */
m->timer = NULL;
static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m)
{
- unsigned long remain = thread_timer_remain_second(m->timer);
+ unsigned long remain = event_timer_remain_second(m->timer);
/* unexpected case, but avoid wraparound problems below */
if (remain > m->rfd->response_lifetime)
if (m->rfd->response_lifetime - remain < 2)
return;
- THREAD_OFF(m->timer);
+ EVENT_OFF(m->timer);
{
char buf[BUFSIZ];
m->rfd->response_lifetime);
}
- thread_add_timer(bm->master, rfapiMonitorTimerExpire, m,
- m->rfd->response_lifetime, &m->timer);
+ event_add_timer(bm->master, rfapiMonitorTimerExpire, m,
+ m->rfd->response_lifetime, &m->timer);
}
/*
}
}
-static void rfapiMonitorEthTimerExpire(struct thread *t)
+static void rfapiMonitorEthTimerExpire(struct event *t)
{
- struct rfapi_monitor_eth *m = THREAD_ARG(t);
+ struct rfapi_monitor_eth *m = EVENT_ARG(t);
/* forget reference to thread, it's gone */
m->timer = NULL;
static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m)
{
- unsigned long remain = thread_timer_remain_second(m->timer);
+ unsigned long remain = event_timer_remain_second(m->timer);
/* unexpected case, but avoid wraparound problems below */
if (remain > m->rfd->response_lifetime)
if (m->rfd->response_lifetime - remain < 2)
return;
- THREAD_OFF(m->timer);
+ EVENT_OFF(m->timer);
{
char buf[BUFSIZ];
m->rfd->response_lifetime);
}
- thread_add_timer(bm->master, rfapiMonitorEthTimerExpire, m,
- m->rfd->response_lifetime, &m->timer);
+ event_add_timer(bm->master, rfapiMonitorEthTimerExpire, m,
+ m->rfd->response_lifetime, &m->timer);
}
static int mon_eth_cmp(const void *a, const void *b)
rfapiMonitorEthDetachImport(bgp, val);
}
- THREAD_OFF(val->timer);
+ EVENT_OFF(val->timer);
/*
* remove from rfd list
#define RFAPI_MON_FLAG_NEEDCALLBACK 0x00000001 /* deferred callback */
// int dcount; /* debugging counter */
- struct thread *timer;
+ struct event *timer;
};
struct rfapi_monitor_encap {
struct rfapi_descriptor *rfd; /* which NVE requested the route */
struct ethaddr macaddr;
uint32_t logical_net_id;
- struct thread *timer;
+ struct event *timer;
};
/*
struct bgp *bgp = bgp_get_default();
uint32_t t_pfx_active = 0;
- uint32_t t_pfx_deleted = 0;
uint32_t t_ri_active = 0;
uint32_t t_ri_deleted = 0;
afi_t afi;
uint32_t pfx_active = 0;
- uint32_t pfx_deleted = 0;
for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
if (dsl) {
ri_deleted = skiplist_count(dsl);
t_ri_deleted += ri_deleted;
- ++pfx_deleted;
- ++t_pfx_deleted;
}
}
for (rn = agg_route_top(rfd->rib_pending[afi]); rn;
if (goner->timer) {
struct rfapi_rib_tcb *tcb;
- tcb = THREAD_ARG(goner->timer);
- THREAD_OFF(goner->timer);
+ tcb = EVENT_ARG(goner->timer);
+ EVENT_OFF(goner->timer);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
XFREE(MTYPE_RFAPI_INFO, goner);
/*
* remove route from rib
*/
-static void rfapiRibExpireTimer(struct thread *t)
+static void rfapiRibExpireTimer(struct event *t)
{
- struct rfapi_rib_tcb *tcb = THREAD_ARG(t);
+ struct rfapi_rib_tcb *tcb = EVENT_ARG(t);
RFAPI_RIB_CHECK_COUNTS(1, 0);
struct rfapi_rib_tcb *tcb = NULL;
if (ri->timer) {
- tcb = THREAD_ARG(ri->timer);
- THREAD_OFF(ri->timer);
+ tcb = EVENT_ARG(ri->timer);
+ EVENT_OFF(ri->timer);
} else {
tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE,
sizeof(struct rfapi_rib_tcb));
vnc_zlog_debug_verbose("%s: rfd %p pfx %pRN life %u", __func__, rfd, rn,
ri->lifetime);
- thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime,
- &ri->timer);
+ event_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime,
+ &ri->timer);
}
extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */
if (ri->timer) {
struct rfapi_rib_tcb *tcb;
- tcb = THREAD_ARG(ri->timer);
- THREAD_OFF(ri->timer);
+ tcb = EVENT_ARG(ri->timer);
+ EVENT_OFF(ri->timer);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
if (ori->timer) {
struct rfapi_rib_tcb *tcb;
- tcb = THREAD_ARG(ori->timer);
- THREAD_OFF(ori->timer);
+ tcb = EVENT_ARG(ori->timer);
+ EVENT_OFF(ori->timer);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
if (ri->timer) {
struct rfapi_rib_tcb *tcb;
- tcb = THREAD_ARG(ri->timer);
- THREAD_OFF(ri->timer);
+ tcb = EVENT_ARG(ri->timer);
+ EVENT_OFF(ri->timer);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
RFAPI_RIB_CHECK_COUNTS(0, delete_list->count);
int printedheader = 0;
int routes_total = 0;
int nhs_total = 0;
- int prefixes_total = 0;
- int prefixes_displayed = 0;
- int nves_total = 0;
- int nves_with_routes = 0;
int nves_displayed = 0;
int routes_displayed = 0;
int nhs_displayed = 0;
int printednve = 0;
afi_t afi;
- ++nves_total;
- if (rfd->rib_prefix_count)
- ++nves_with_routes;
-
for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
struct agg_node *rn;
routes_total++;
nhs_total += skiplist_count(sl);
- ++prefixes_total;
if (pfx_match && !prefix_match(pfx_match, p)
&& !prefix_match(p, pfx_match))
continue;
- ++prefixes_displayed;
-
if (!printedheader) {
++printedheader;
struct bgp_tea_options *tea_options;
struct rfapi_un_option *un_options;
struct rfapi_vn_option *vn_options;
- struct thread *timer;
+ struct event *timer;
};
/*
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
&& bpi->extra->vnc.import.timer) {
- struct thread *t =
- (struct thread *)bpi->extra->vnc.import.timer;
+ struct event *t = (struct event *)bpi->extra->vnc.import.timer;
+
r = snprintf(p, REMAIN, " [%4lu] ",
- thread_timer_remain_second(t));
+ event_timer_remain_second(t));
INCP;
} else {
const char *vty_newline;
int printedheader = 0;
-
- int nves_total = 0;
- int nves_with_queries = 0;
- int nves_displayed = 0;
-
int queries_total = 0;
int queries_displayed = 0;
struct agg_node *rn;
int printedquerier = 0;
-
- ++nves_total;
-
- if (rfd->mon
- || (rfd->mon_eth && skiplist_count(rfd->mon_eth))) {
- ++nves_with_queries;
- } else {
+ if (!rfd->mon &&
+ !(rfd->mon_eth && skiplist_count(rfd->mon_eth)))
continue;
- }
/*
* IP Queries
fp(out, "%-15s %-15s", buf_vn, buf_un);
printedquerier = 1;
-
- ++nves_displayed;
} else
fp(out, "%-15s %-15s", "", "");
buf_remain[0] = 0;
rfapiFormatSeconds(
- thread_timer_remain_second(m->timer),
+ event_timer_remain_second(m->timer),
buf_remain, BUFSIZ);
fp(out, " %-15s %-10s\n",
inet_ntop(m->p.family, &m->p.u.prefix,
fp(out, "%-15s %-15s", buf_vn, buf_un);
printedquerier = 1;
-
- ++nves_displayed;
} else
fp(out, "%-15s %-15s", "", "");
buf_remain[0] = 0;
- rfapiFormatSeconds(thread_timer_remain_second(
+ rfapiFormatSeconds(event_timer_remain_second(
mon_eth->timer),
buf_remain, BUFSIZ);
fp(out, " %-17s %10d %-10s\n",
time_t age;
char buf_age[BUFSIZ];
- struct thread *t =
- (struct thread *)bpi->extra->vnc.import.timer;
- remaining = thread_timer_remain_second(t);
+ struct event *t = (struct event *)bpi->extra->vnc.import.timer;
+ remaining = event_timer_remain_second(t);
#ifdef RFAPI_REGISTRATIONS_REPORT_AGE
/*
}
if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra) {
uint32_t l = decode_label(&bpi->extra->label[0]);
+
if (!MPLS_LABEL_IS_NULL(l)) {
fp(out, " Label: %d", l);
if (nlines == 1)
* export expiration timer is already running on
* this route: cancel it
*/
- THREAD_OFF(eti->timer);
+ EVENT_OFF(eti->timer);
bgp_update(peer, prefix, /* prefix */
0, /* addpath_id */
bgp_attr_unintern(&iattr);
}
-static void vncExportWithdrawTimer(struct thread *t)
+static void vncExportWithdrawTimer(struct event *t)
{
- struct vnc_export_info *eti = THREAD_ARG(t);
+ struct vnc_export_info *eti = EVENT_ARG(t);
const struct prefix *p = agg_node_get_prefix(eti->node);
/*
if (!eti->timer && eti->lifetime <= INT32_MAX) {
eti->timer = NULL;
- thread_add_timer(bm->master, vncExportWithdrawTimer, eti,
- eti->lifetime, &eti->timer);
+ event_add_timer(bm->master, vncExportWithdrawTimer, eti,
+ eti->lifetime, &eti->timer);
vnc_zlog_debug_verbose(
"%s: set expiration timer for %u seconds", __func__,
eti->lifetime);
* already running on
* this route: cancel it
*/
- THREAD_OFF(eti->timer);
+ EVENT_OFF(eti->timer);
vnc_zlog_debug_verbose(
"%s: calling bgp_update",
ZEBRA_ROUTE_VNC_DIRECT_RH,
BGP_ROUTE_REDISTRIBUTE);
if (eti) {
- THREAD_OFF(eti->timer);
+ EVENT_OFF(eti->timer);
vnc_eti_delete(eti);
}
#define _QUAGGA_VNC_VNC_EXPORT_TABLE_H_
#include "lib/table.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/vty.h"
#include "bgpd/bgpd.h"
uint8_t type;
uint8_t subtype;
uint32_t lifetime;
- struct thread *timer;
+ struct event *timer;
};
extern struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
if (RFAPI_HAS_MONITOR_EXTERIOR(rn_interior)) {
- int count = 0; /* debugging */
-
vnc_zlog_debug_verbose(
"%s: has exterior monitor; ext src: %p", __func__,
RFAPI_MONITOR_EXTERIOR(rn_interior)->source);
struct attr new_attr;
uint32_t label = 0;
-
- ++count; /* debugging */
-
assert(bpi_exterior);
assert(pfx_exterior);
* Modeled after bgp_zebra.c'bgp_zebra_init()
* Charriere asks, "Is it possible to carry two?"
*/
-void vnc_zebra_init(struct thread_master *master)
+void vnc_zebra_init(struct event_loop *master)
{
/* Set default values. */
zclient_vnc = zclient_new(master, &zclient_options_default,
struct rfp_instance_t {
struct rfapi_rfp_cfg rfapi_config;
struct rfapi_rfp_cb_methods rfapi_callbacks;
- struct thread_master *master;
+ struct event_loop *master;
uint32_t config_var;
};
* rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write
*
--------------------------------------------*/
-void *rfp_start(struct thread_master *master, struct rfapi_rfp_cfg **cfgp,
+void *rfp_start(struct event_loop *master, struct rfapi_rfp_cfg **cfgp,
struct rfapi_rfp_cb_methods **cbmp)
{
memset(&global_rfi, 0, sizeof(global_rfi));
CFG_SYSCONF="$sysconfdir"
CFG_SBIN="$sbindir"
+CFG_BIN="$bindir"
CFG_STATE="$frr_statedir"
CFG_MODULE="$moduledir"
CFG_YANGMODELS="$yangmodelsdir"
for I in 1 2 3 4 5 6 7 8 9 10; do
eval CFG_SYSCONF="\"$CFG_SYSCONF\""
eval CFG_SBIN="\"$CFG_SBIN\""
+ eval CFG_BIN="\"$CFG_BIN\""
eval CFG_STATE="\"$CFG_STATE\""
eval CFG_MODULE="\"$CFG_MODULE\""
eval CFG_YANGMODELS="\"$CFG_YANGMODELS\""
done
AC_SUBST([CFG_SYSCONF])
AC_SUBST([CFG_SBIN])
+AC_SUBST([CFG_BIN])
AC_SUBST([CFG_STATE])
AC_SUBST([CFG_MODULE])
AC_SUBST([CFG_SCRIPT])
FRR library helper formats
^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. frrfmt:: %pTH (struct thread *)
+.. frrfmt:: %pTH (struct event *)
- Print remaining time on timer thread. Interval-printing flag characters
+ Print remaining time on timer event. Interval-printing flag characters
listed above for ``%pTV`` can be added, e.g. ``%pTHtx``.
``NULL`` pointers are printed as ``-``.
-.. frrfmt:: %pTHD (struct thread *)
+.. frrfmt:: %pTHD (struct event *)
- Print debugging information for given thread. Sample output:
+ Print debugging information for given event. Sample output:
.. code-block:: none
#include "hook.h"
#include "module.h"
#include "libfrr.h"
- #include "thread.h"
+ #include "frrevent.h"
- static int module_late_init(struct thread_master *master)
+ static int module_late_init(struct event_loop *master)
{
/* Do initialization stuff here */
return 0;
Part of the controller code runs in FRR main thread and part runs in its own
FRR pthread started to isolate the main thread from the PCCs' event loop.
To communicate between the threads it uses FRR events, timers and
-`thread_execute` calls.
+`event_execute` calls.
PCC
datastructure that holds the state of an event loop in this system is called a
"threadmaster". Events scheduled on the event loop - what would today be called
an 'event' or 'task' in systems such as libevent - are called "threads" and the
-datastructure for them is ``struct thread``. To add to the confusion, these
+datastructure for them is ``struct event``. To add to the confusion, these
"threads" have various types, one of which is "event". To hopefully avoid some
of this confusion, this document refers to these "threads" as a 'task' except
where the datastructures are explicitly named. When they are explicitly named,
interplay between the event system and kernel threads.
The core event system is implemented in :file:`lib/thread.[ch]`. The primary
-structure is ``struct thread_master``, hereafter referred to as a
+structure is ``struct event_loop``, hereafter referred to as a
``threadmaster``. A ``threadmaster`` is a global state object, or context, that
holds all the tasks currently pending execution as well as statistics on tasks
that have already executed. The event system is driven by adding tasks to this
fetch each task and execute it.
These tasks have various types corresponding to their general action. The types
-are given by integer macros in :file:`thread.h` and are:
+are given by integer macros in :file:`event.h` and are:
``THREAD_READ``
Task which waits for a file descriptor to become ready for reading and then
Type used internally for tasks on the ready queue.
``THREAD_UNUSED``
- Type used internally for ``struct thread`` objects that aren't being used.
- The event system pools ``struct thread`` to avoid heap allocations; this is
+ Type used internally for ``struct event`` objects that aren't being used.
+ The event system pools ``struct event`` to avoid heap allocations; this is
the type they have when they're in the pool.
``THREAD_EXECUTE``
::
- thread_add_read(struct thread_master *master, int (*handler)(struct thread *), void *arg, int fd, struct thread **ref);
+ event_add_read(struct event_loop *master, int (*handler)(struct event *), void *arg, int fd, struct event **ref);
-The ``struct thread`` is then created and added to the appropriate internal
+The ``struct event`` is then created and added to the appropriate internal
datastructure within the ``threadmaster``. Note that the ``READ`` and
``WRITE`` tasks are independent - a ``READ`` task only tests for
readability, for example.
startup the first task added is an I/O task for VTYSH as well as any network
sockets needed for peerings or IPC.
-To retrieve the next task to run the program calls ``thread_fetch()``.
-``thread_fetch()`` internally computes which task to execute next based on
+To retrieve the next task to run the program calls ``event_fetch()``.
+``event_fetch()`` internally computes which task to execute next based on
rudimentary priority logic. Events (type ``THREAD_EVENT``) execute with the
highest priority, followed by expired timers and finally I/O tasks (type
``THREAD_READ`` and ``THREAD_WRITE``). When scheduling a task a function and an
-arbitrary argument are provided. The task returned from ``thread_fetch()`` is
-then executed with ``thread_call()``.
+arbitrary argument are provided. The task returned from ``event_fetch()`` is
+then executed with ``event_call()``.
The following diagram illustrates a simplified version of this infrastructure.
Mapping the general names used in the figure to specific FRR functions:
-- ``task`` is ``struct thread *``
-- ``fetch`` is ``thread_fetch()``
-- ``exec()`` is ``thread_call``
-- ``cancel()`` is ``thread_cancel()``
-- ``schedule()`` is any of the various task-specific ``thread_add_*`` functions
+- ``task`` is ``struct event *``
+- ``fetch`` is ``event_fetch()``
+- ``exec()`` is ``event_call``
+- ``cancel()`` is ``event_cancel()``
+- ``schedule()`` is any of the various task-specific ``event_add_*`` functions
Adding tasks is done with various task-specific function-like macros. These
macros wrap underlying functions in :file:`thread.c` to provide additional
information added at compile time, such as the line number the task was
scheduled from, that can be accessed at runtime for debugging, logging and
informational purposes. Each task type has its own specific scheduling function
-that follow the naming convention ``thread_add_<type>``; see :file:`thread.h`
+that follow the naming convention ``event_add_<type>``; see :file:`event.h`
for details.
There are some gotchas to keep in mind:
communication and boils down to a slightly more complicated method of message
passing, where the messages are the regular task events as used in the
event-driven model. The only difference is thread cancellation, which requires
-calling ``thread_cancel_async()`` instead of ``thread_cancel`` to cancel a task
+calling ``event_cancel_async()`` instead of ``event_cancel`` to cancel a task
currently scheduled on a ``threadmaster`` belonging to a different pthread.
This is necessary to avoid race conditions in the specific case where one
pthread wants to guarantee that a task on another pthread is cancelled before
The ``thread_master`` code currently always holds RCU everywhere, except
while doing the actual ``poll()`` syscall. This is both an optimization as
well as an "easement" into getting RCU going. The current implementation
- contract is that any ``struct thread *`` callback is called with a RCU
+ contract is that any ``struct event *`` callback is called with a RCU
holding depth of 1, and that this is owned by the thread so it may (should)
drop and reacquire it when doing some longer-running work.
frr_libfrr:frr_pthread_stop (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
frr_libfrr:frr_pthread_run (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
frr_libfrr:thread_call (loglevel: TRACE_INFO (6)) (type: tracepoint)
- frr_libfrr:thread_cancel_async (loglevel: TRACE_INFO (6)) (type: tracepoint)
- frr_libfrr:thread_cancel (loglevel: TRACE_INFO (6)) (type: tracepoint)
+ frr_libfrr:event_cancel_async (loglevel: TRACE_INFO (6)) (type: tracepoint)
+ frr_libfrr:event_cancel (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_libfrr:schedule_write (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_libfrr:schedule_read (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_libfrr:schedule_event (loglevel: TRACE_INFO (6)) (type: tracepoint)
Display a usage message on standard output and exit.
+.. option:: -t, --timestamp
+
+ Print a timestamp before going to shell or reading the configuration file.
+
+.. option:: --no-fork
+
+ When used in conjunction with ``-b``, prevents vtysh from forking children to handle configuring each target daemon.
+
+
ENVIRONMENT VARIABLES
=====================
VTYSH_PAGER
Allow using IPv4 reserved (Class E) IP ranges for daemons. E.g.: setting
IPv4 addresses for interfaces or allowing reserved ranges in BGP next-hops.
+ If you need multiple FRR instances (or FRR + any other daemon) running in a
+ single router and peering via 127.0.0.0/8, it's also possible to use this
+ knob if turned on.
+
Default: off.
.. _sample-config-file:
:t:`Extended Optional Parameters Length for BGP OPEN Message. E. Chen, J. Scudder. July 2021.`
- :rfc:`9234`
:t:`Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages. A. Azimov, E. Bogomazov, R. Bush, K. Patel, K. Sriram. May 2022.`
+- :rfc:`9384`
+ :t:`A BGP Cease NOTIFICATION Subcode for Bidirectional Forwarding Detection (BFD). J. Haas. March 2023.`
OSPF
----
#include <zebra.h>
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "command.h"
#include "stream.h"
vty_out(vty, "%-3u %-17pI4 %-21s", 0, &nbr->src, IF_NAME(nbr->ei));
if (nbr->t_holddown)
vty_out(vty, "%-7lu",
- thread_timer_remain_second(nbr->t_holddown));
+ event_timer_remain_second(nbr->t_holddown));
else
vty_out(vty, "- ");
vty_out(vty, "%-8u %-6u %-5u", 0, 0, EIGRP_PACKET_RETRANS_TIME);
#include "command.h"
#include "prefix.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "log.h"
#include "stream.h"
// TODO: check Graceful restart after 10sec
/* cancel GR scheduled */
- thread_cancel(&(e->t_distribute));
+ event_cancel(&(e->t_distribute));
/* schedule Graceful restart for whole process in 10sec */
- thread_add_timer(master, eigrp_distribute_timer_process, e,
- (10), &e->t_distribute);
+ event_add_timer(master, eigrp_distribute_timer_process, e, (10),
+ &e->t_distribute);
return;
}
// TODO: check Graceful restart after 10sec
/* Cancel GR scheduled */
- thread_cancel(&(ei->t_distribute));
+ event_cancel(&(ei->t_distribute));
/* schedule Graceful restart for interface in 10sec */
- thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
- &ei->t_distribute);
+ event_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
+ &ei->t_distribute);
}
/*
* Called when 10sec waiting time expire and
* executes Graceful restart for whole process
*/
-void eigrp_distribute_timer_process(struct thread *thread)
+void eigrp_distribute_timer_process(struct event *thread)
{
struct eigrp *eigrp;
- eigrp = THREAD_ARG(thread);
+ eigrp = EVENT_ARG(thread);
/* execute GR for whole process */
eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL);
* Called when 10sec waiting time expire and
* executes Graceful restart for interface
*/
-void eigrp_distribute_timer_interface(struct thread *thread)
+void eigrp_distribute_timer_interface(struct event *thread)
{
struct eigrp_interface *ei;
- ei = THREAD_ARG(thread);
+ ei = EVENT_ARG(thread);
ei->t_distribute = NULL;
/* execute GR for interface */
extern void eigrp_distribute_update_interface(struct interface *ifp);
extern void eigrp_distribute_update_all(struct prefix_list *plist);
extern void eigrp_distribute_update_all_wrapper(struct access_list *alist);
-extern void eigrp_distribute_timer_process(struct thread *thread);
-extern void eigrp_distribute_timer_interface(struct thread *thread);
+extern void eigrp_distribute_timer_process(struct event *thread);
+extern void eigrp_distribute_timer_interface(struct event *thread);
#endif /* EIGRPD_EIGRP_FILTER_H_ */
*/
#include <zebra.h>
-#include <thread.h>
+#include "frrevent.h"
#include "prefix.h"
#include "table.h"
#include "memory.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
* Sends hello packet via multicast for all interfaces eigrp
* is configured for
*/
-void eigrp_hello_timer(struct thread *thread)
+void eigrp_hello_timer(struct event *thread)
{
struct eigrp_interface *ei;
- ei = THREAD_ARG(thread);
+ ei = EVENT_ARG(thread);
if (IS_DEBUG_EIGRP(0, TIMERS))
zlog_debug("Start Hello Timer (%s) Expire [%u]", IF_NAME(ei),
eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL);
/* Hello timer set. */
- thread_add_timer(master, eigrp_hello_timer, ei, ei->params.v_hello,
- &ei->t_hello);
+ event_add_timer(master, eigrp_hello_timer, ei, ei->params.v_hello,
+ &ei->t_hello);
}
/**
listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
nbr->ei->on_write_q = 1;
}
- thread_add_write(master, eigrp_write, nbr->ei->eigrp,
- nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
+ event_add_write(master, eigrp_write, nbr->ei->eigrp,
+ nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
}
}
if (ei->eigrp->t_write == NULL) {
if (flags & EIGRP_HELLO_GRACEFUL_SHUTDOWN) {
- thread_execute(master, eigrp_write, ei->eigrp,
- ei->eigrp->fd);
+ event_execute(master, eigrp_write, ei->eigrp,
+ ei->eigrp->fd);
} else {
- thread_add_write(master, eigrp_write, ei->eigrp,
- ei->eigrp->fd,
- &ei->eigrp->t_write);
+ event_add_write(master, eigrp_write, ei->eigrp,
+ ei->eigrp->fd,
+ &ei->eigrp->t_write);
}
}
}
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
/* Set multicast memberships appropriately for new state. */
eigrp_if_set_multicast(ei);
- thread_add_event(master, eigrp_hello_timer, ei, (1), &ei->t_hello);
+ event_add_event(master, eigrp_hello_timer, ei, (1), &ei->t_hello);
/*Prepare metrics*/
metric.bandwidth = eigrp_bandwidth_to_scaled(ei->params.bandwidth);
return 0;
/* Shutdown packet reception and sending */
- THREAD_OFF(ei->t_hello);
+ EVENT_OFF(ei->t_hello);
eigrp_if_stream_unset(ei);
if (ei->on_write_q) {
listnode_delete(eigrp->oi_write_q, ei);
if (list_isempty(eigrp->oi_write_q))
- thread_cancel(&(eigrp->t_write));
+ event_cancel(&(eigrp->t_write));
ei->on_write_q = 0;
}
}
struct eigrp *eigrp = ei->eigrp;
if (source == INTERFACE_DOWN_BY_VTY) {
- thread_cancel(&ei->t_hello);
+ event_cancel(&ei->t_hello);
eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
}
/* FSM macros*/
#define EIGRP_FSM_EVENT_SCHEDULE(I, E) \
- thread_add_event(master, eigrp_fsm_event, (I), (E))
+ event_add_event(master, eigrp_fsm_event, (I), (E))
#endif /* _ZEBRA_EIGRP_MACROS_H_ */
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "linklist.h"
#include "if.h"
struct option longopts[] = {{0}};
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/* Forward declaration of daemon info structure. */
static struct frr_daemon_info eigrpd_di;
#include "prefix.h"
#include "memory.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#include "table.h"
#include "log.h"
eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr);
/* Cancel all events. */ /* Thread lookup cost would be negligible. */
- thread_cancel_event(master, nbr);
+ event_cancel_event(master, nbr);
eigrp_fifo_free(nbr->multicast_queue);
eigrp_fifo_free(nbr->retrans_queue);
- THREAD_OFF(nbr->t_holddown);
+ EVENT_OFF(nbr->t_holddown);
if (nbr->ei)
listnode_delete(nbr->ei->nbrs, nbr);
XFREE(MTYPE_EIGRP_NEIGHBOR, nbr);
}
-void holddown_timer_expired(struct thread *thread)
+void holddown_timer_expired(struct event *thread)
{
- struct eigrp_neighbor *nbr = THREAD_ARG(thread);
+ struct eigrp_neighbor *nbr = EVENT_ARG(thread);
struct eigrp *eigrp = nbr->ei->eigrp;
zlog_info("Neighbor %pI4 (%s) is down: holding time expired", &nbr->src,
// hold time..
nbr->v_holddown = EIGRP_HOLD_INTERVAL_DEFAULT;
- THREAD_OFF(nbr->t_holddown);
+ EVENT_OFF(nbr->t_holddown);
/* out with the old */
if (nbr->multicast_queue)
switch (nbr->state) {
case EIGRP_NEIGHBOR_DOWN: {
/*Start Hold Down Timer for neighbor*/
- // THREAD_OFF(nbr->t_holddown);
- // THREAD_TIMER_ON(master, nbr->t_holddown,
+ // EVENT_OFF(nbr->t_holddown);
+ // EVENT_TIMER_ON(master, nbr->t_holddown,
// holddown_timer_expired,
// nbr, nbr->v_holddown);
break;
}
case EIGRP_NEIGHBOR_PENDING: {
/*Reset Hold Down Timer for neighbor*/
- THREAD_OFF(nbr->t_holddown);
- thread_add_timer(master, holddown_timer_expired, nbr,
- nbr->v_holddown, &nbr->t_holddown);
+ EVENT_OFF(nbr->t_holddown);
+ event_add_timer(master, holddown_timer_expired, nbr,
+ nbr->v_holddown, &nbr->t_holddown);
break;
}
case EIGRP_NEIGHBOR_UP: {
/*Reset Hold Down Timer for neighbor*/
- THREAD_OFF(nbr->t_holddown);
- thread_add_timer(master, holddown_timer_expired, nbr,
- nbr->v_holddown, &nbr->t_holddown);
+ EVENT_OFF(nbr->t_holddown);
+ event_add_timer(master, holddown_timer_expired, nbr,
+ nbr->v_holddown, &nbr->t_holddown);
break;
}
}
extern struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *ei);
extern void eigrp_nbr_delete(struct eigrp_neighbor *neigh);
-extern void holddown_timer_expired(struct thread *thread);
+extern void holddown_timer_expired(struct event *thread);
extern int eigrp_neighborship_check(struct eigrp_neighbor *neigh,
struct TLV_Parameter_Type *tlv);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
extern int eigrp_network_set(struct eigrp *eigrp, struct prefix *p);
extern int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p);
-extern void eigrp_hello_timer(struct thread *thread);
+extern void eigrp_hello_timer(struct event *thread);
extern void eigrp_if_update(struct interface *);
extern int eigrp_if_add_allspfrouters(struct eigrp *, struct prefix *,
unsigned int);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "vty.h"
return 1;
}
-void eigrp_write(struct thread *thread)
+void eigrp_write(struct event *thread)
{
- struct eigrp *eigrp = THREAD_ARG(thread);
+ struct eigrp *eigrp = EVENT_ARG(thread);
struct eigrp_header *eigrph;
struct eigrp_interface *ei;
struct eigrp_packet *ep;
/* If packets still remain in queue, call write thread. */
if (!list_isempty(eigrp->oi_write_q)) {
- thread_add_write(master, eigrp_write, eigrp, eigrp->fd,
- &eigrp->t_write);
+ event_add_write(master, eigrp_write, eigrp, eigrp->fd,
+ &eigrp->t_write);
}
}
/* Starting point of packet process function. */
-void eigrp_read(struct thread *thread)
+void eigrp_read(struct event *thread)
{
int ret;
struct stream *ibuf;
uint16_t length = 0;
/* first of all get interface pointer. */
- eigrp = THREAD_ARG(thread);
+ eigrp = EVENT_ARG(thread);
/* prepare for next packet. */
- thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
+ event_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
stream_reset(eigrp->ibuf);
if (!(ibuf = eigrp_recv_packet(eigrp, eigrp->fd, &ifp, eigrp->ibuf))) {
eigrp_fifo_push(nbr->ei->obuf, duplicate);
/*Start retransmission timer*/
- thread_add_timer(master, eigrp_unack_packet_retrans, nbr,
- EIGRP_PACKET_RETRANS_TIME,
- &ep->t_retrans_timer);
+ event_add_timer(master, eigrp_unack_packet_retrans, nbr,
+ EIGRP_PACKET_RETRANS_TIME,
+ &ep->t_retrans_timer);
/*Increment sequence number counter*/
nbr->ei->eigrp->sequence_number++;
listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
nbr->ei->on_write_q = 1;
}
- thread_add_write(master, eigrp_write, nbr->ei->eigrp,
- nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
+ event_add_write(master, eigrp_write, nbr->ei->eigrp,
+ nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
}
}
if (ep->s)
stream_free(ep->s);
- THREAD_OFF(ep->t_retrans_timer);
+ EVENT_OFF(ep->t_retrans_timer);
XFREE(MTYPE_EIGRP_PACKET, ep);
}
return 0;
}
-void eigrp_unack_packet_retrans(struct thread *thread)
+void eigrp_unack_packet_retrans(struct event *thread)
{
struct eigrp_neighbor *nbr;
- nbr = (struct eigrp_neighbor *)THREAD_ARG(thread);
+ nbr = (struct eigrp_neighbor *)EVENT_ARG(thread);
struct eigrp_packet *ep;
ep = eigrp_fifo_next(nbr->retrans_queue);
}
/*Start retransmission timer*/
- thread_add_timer(master, eigrp_unack_packet_retrans, nbr,
- EIGRP_PACKET_RETRANS_TIME,
- &ep->t_retrans_timer);
+ event_add_timer(master, eigrp_unack_packet_retrans, nbr,
+ EIGRP_PACKET_RETRANS_TIME,
+ &ep->t_retrans_timer);
/* Hook thread to write packet. */
if (nbr->ei->on_write_q == 0) {
listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
nbr->ei->on_write_q = 1;
}
- thread_add_write(master, eigrp_write, nbr->ei->eigrp,
- nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
+ event_add_write(master, eigrp_write, nbr->ei->eigrp,
+ nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
}
}
-void eigrp_unack_multicast_packet_retrans(struct thread *thread)
+void eigrp_unack_multicast_packet_retrans(struct event *thread)
{
struct eigrp_neighbor *nbr;
- nbr = (struct eigrp_neighbor *)THREAD_ARG(thread);
+ nbr = (struct eigrp_neighbor *)EVENT_ARG(thread);
struct eigrp_packet *ep;
ep = eigrp_fifo_next(nbr->multicast_queue);
}
/*Start retransmission timer*/
- thread_add_timer(master, eigrp_unack_multicast_packet_retrans,
- nbr, EIGRP_PACKET_RETRANS_TIME,
- &ep->t_retrans_timer);
+ event_add_timer(master, eigrp_unack_multicast_packet_retrans,
+ nbr, EIGRP_PACKET_RETRANS_TIME,
+ &ep->t_retrans_timer);
/* Hook thread to write packet. */
if (nbr->ei->on_write_q == 0) {
listnode_add(nbr->ei->eigrp->oi_write_q, nbr->ei);
nbr->ei->on_write_q = 1;
}
- thread_add_write(master, eigrp_write, nbr->ei->eigrp,
- nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
+ event_add_write(master, eigrp_write, nbr->ei->eigrp,
+ nbr->ei->eigrp->fd, &nbr->ei->eigrp->t_write);
}
}
#define _ZEBRA_EIGRP_PACKET_H
/*Prototypes*/
-extern void eigrp_read(struct thread *thread);
-extern void eigrp_write(struct thread *thread);
+extern void eigrp_read(struct event *thread);
+extern void eigrp_write(struct event *thread);
extern struct eigrp_packet *eigrp_packet_new(size_t size,
struct eigrp_neighbor *nbr);
extern uint16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *s,
struct eigrp_interface *ei);
-extern void eigrp_unack_packet_retrans(struct thread *thread);
-extern void eigrp_unack_multicast_packet_retrans(struct thread *thread);
+extern void eigrp_unack_packet_retrans(struct event *thread);
+extern void eigrp_unack_multicast_packet_retrans(struct event *thread);
/*
* untill there is reason to have their own header, these externs are found in
extern void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
struct eigrp_header *eigrph, struct stream *s,
struct eigrp_interface *ei, int size);
-extern void eigrp_hello_timer(struct thread *thread);
+extern void eigrp_hello_timer(struct event *thread);
/*
* These externs are found in eigrp_update.c
struct eigrp_interface *exception);
extern void eigrp_update_send_init(struct eigrp_neighbor *nbr);
extern void eigrp_update_send_EOT(struct eigrp_neighbor *nbr);
-extern void eigrp_update_send_GR_thread(struct thread *thread);
+extern void eigrp_update_send_GR_thread(struct event *thread);
extern void eigrp_update_send_GR(struct eigrp_neighbor *nbr,
enum GR_type gr_type, struct vty *vty);
extern void eigrp_update_send_interface_GR(struct eigrp_interface *ei,
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
struct list *oi_write_q;
/*Threads*/
- struct thread *t_write;
- struct thread *t_read;
- struct thread *t_distribute; /* timer for distribute list */
+ struct event *t_write;
+ struct event *t_read;
+ struct event *t_distribute; /* timer for distribute list */
struct route_table *networks; /* EIGRP config networks. */
struct list *nbrs; /* EIGRP Neighbor List */
/* Threads. */
- struct thread *t_hello; /* timer */
- struct thread *t_distribute; /* timer for distribute list */
+ struct event *t_hello; /* timer */
+ struct event *t_distribute; /* timer for distribute list */
int on_write_q;
uint16_t v_holddown;
/* Threads. */
- struct thread *t_holddown;
- struct thread *t_nbr_send_gr; /* thread for sending multiple GR packet
+ struct event *t_holddown;
+ struct event *t_nbr_send_gr; /* thread for sending multiple GR packet
chunks */
struct eigrp_fifo *retrans_queue;
struct in_addr dst;
/*Packet retransmission thread*/
- struct thread *t_retrans_timer;
+ struct event *t_retrans_timer;
/*Packet retransmission counter*/
uint8_t retrans_counter;
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
*
* Uses nbr_gr_packet_type and t_nbr_send_gr from neighbor.
*/
-void eigrp_update_send_GR_thread(struct thread *thread)
+void eigrp_update_send_GR_thread(struct event *thread)
{
struct eigrp_neighbor *nbr;
/* get argument from thread */
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
/* remove this thread pointer */
/* if there is packet waiting in queue,
* schedule this thread again with small delay */
if (nbr->retrans_queue->count > 0) {
- thread_add_timer_msec(master, eigrp_update_send_GR_thread, nbr,
- 10, &nbr->t_nbr_send_gr);
+ event_add_timer_msec(master, eigrp_update_send_GR_thread, nbr,
+ 10, &nbr->t_nbr_send_gr);
return;
}
/* if it wasn't last chunk, schedule this thread again */
if (nbr->nbr_gr_packet_type != EIGRP_PACKET_PART_LAST) {
- thread_execute(master, eigrp_update_send_GR_thread, nbr, 0);
+ event_execute(master, eigrp_update_send_GR_thread, nbr, 0);
}
}
/* indicate, that this is first GR Update packet chunk */
nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_FIRST;
/* execute packet sending in thread */
- thread_execute(master, eigrp_update_send_GR_thread, nbr, 0);
+ event_execute(master, eigrp_update_send_GR_thread, nbr, 0);
}
/**
#include <zebra.h>
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "table.h"
#include "vty.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "network.h"
#include "prefix.h"
struct zclient *zclient = NULL;
/* For registering threads. */
-extern struct thread_master *master;
+extern struct event_loop *master;
struct in_addr router_id_zebra;
/* Router-id update message from zebra. */
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "linklist.h"
eigrp->ibuf = stream_new(EIGRP_PACKET_MAX_LEN + 1);
- thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
+ event_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
eigrp->oi_write_q = list_new();
eigrp->topology_table = route_table_init();
eigrp_if_free(ei, INTERFACE_DOWN_BY_FINAL);
}
- THREAD_OFF(eigrp->t_write);
- THREAD_OFF(eigrp->t_read);
+ EVENT_OFF(eigrp->t_write);
+ EVENT_OFF(eigrp->t_read);
close(eigrp->fd);
list_delete(&eigrp->eiflist);
struct list *eigrp;
/* EIGRP thread master. */
- struct thread_master *master;
+ struct event_loop *master;
/* Zebra interface list. */
struct list *iflist;
/* Extern variables. */
extern struct zclient *zclient;
-extern struct thread_master *master;
+extern struct event_loop *master;
extern struct eigrp_master *eigrp_om;
extern struct zebra_privs_t eigrpd_privs;
Walk through a routing table (or subset thereof) and dump all the non-null
(struct route_node *)->info pointers.
-Argument: A lib/thread.h::(struct route_node *) pointing to the route_node
+Argument: A lib/hread.h::(struct route_node *) pointing to the route_node
under which all data should be dumped
end
enum fabricd_sync_state initial_sync_state;
time_t initial_sync_start;
struct isis_circuit *initial_sync_circuit;
- struct thread *initial_sync_timeout;
+ struct event *initial_sync_timeout;
struct isis_spftree *spftree;
struct skiplist *neighbors;
uint8_t tier;
uint8_t tier_config;
uint8_t tier_pending;
- struct thread *tier_calculation_timer;
- struct thread *tier_set_timer;
+ struct event *tier_calculation_timer;
+ struct event *tier_set_timer;
int csnp_delay;
bool always_send_csnp;
void fabricd_finish(struct fabricd *f)
{
- THREAD_OFF(f->initial_sync_timeout);
+ EVENT_OFF(f->initial_sync_timeout);
- THREAD_OFF(f->tier_calculation_timer);
+ EVENT_OFF(f->tier_calculation_timer);
- THREAD_OFF(f->tier_set_timer);
+ EVENT_OFF(f->tier_set_timer);
isis_spftree_del(f->spftree);
neighbor_lists_clear(f);
hash_free(f->neighbors_neighbors);
}
-static void fabricd_initial_sync_timeout(struct thread *thread)
+static void fabricd_initial_sync_timeout(struct event *thread)
{
- struct fabricd *f = THREAD_ARG(thread);
+ struct fabricd *f = EVENT_ARG(thread);
if (IS_DEBUG_ADJ_PACKETS)
zlog_debug(
if (f->initial_sync_timeout)
return;
- thread_add_timer(master, fabricd_initial_sync_timeout, f,
- timeout, &f->initial_sync_timeout);
+ event_add_timer(master, fabricd_initial_sync_timeout, f, timeout,
+ &f->initial_sync_timeout);
f->initial_sync_start = monotime(NULL);
if (IS_DEBUG_ADJ_PACKETS)
f->initial_sync_circuit->interface->name);
f->initial_sync_state = FABRICD_SYNC_COMPLETE;
f->initial_sync_circuit = NULL;
- THREAD_OFF(f->initial_sync_timeout);
+ EVENT_OFF(f->initial_sync_timeout);
}
static void fabricd_bump_tier_calculation_timer(struct fabricd *f);
return tier;
}
-static void fabricd_tier_set_timer(struct thread *thread)
+static void fabricd_tier_set_timer(struct event *thread)
{
- struct fabricd *f = THREAD_ARG(thread);
+ struct fabricd *f = EVENT_ARG(thread);
fabricd_set_tier(f, f->tier_pending);
}
-static void fabricd_tier_calculation_cb(struct thread *thread)
+static void fabricd_tier_calculation_cb(struct event *thread)
{
- struct fabricd *f = THREAD_ARG(thread);
+ struct fabricd *f = EVENT_ARG(thread);
uint8_t tier = ISIS_TIER_UNDEFINED;
tier = fabricd_calculate_fabric_tier(f->area);
zlog_info("OpenFabric: Got tier %hhu from algorithm. Arming timer.",
tier);
f->tier_pending = tier;
- thread_add_timer(master, fabricd_tier_set_timer, f,
- f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
- &f->tier_set_timer);
-
+ event_add_timer(master, fabricd_tier_set_timer, f,
+ f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
+ &f->tier_set_timer);
}
static void fabricd_bump_tier_calculation_timer(struct fabricd *f)
{
/* Cancel timer if we already know our tier */
if (f->tier != ISIS_TIER_UNDEFINED || f->tier_set_timer) {
- THREAD_OFF(f->tier_calculation_timer);
+ EVENT_OFF(f->tier_calculation_timer);
return;
}
/* If we need to calculate the tier, wait some
* time for the topology to settle before running
* the calculation */
- THREAD_OFF(f->tier_calculation_timer);
+ EVENT_OFF(f->tier_calculation_timer);
- thread_add_timer(master, fabricd_tier_calculation_cb, f,
- 2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
- &f->tier_calculation_timer);
+ event_add_timer(master, fabricd_tier_calculation_cb, f,
+ 2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
+ &f->tier_calculation_timer);
}
static void fabricd_set_tier(struct fabricd *f, uint8_t tier)
if (!circuit->t_send_csnp[1])
continue;
- THREAD_OFF(circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
- thread_add_timer_msec(master, send_l2_csnp, circuit,
- isis_jitter(f->csnp_delay, CSNP_JITTER),
- &circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
+ EVENT_OFF(circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
+ event_add_timer_msec(master, send_l2_csnp, circuit,
+ isis_jitter(f->csnp_delay, CSNP_JITTER),
+ &circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
}
}
#include "hash.h"
#include "vty.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "if.h"
#include "stream.h"
#include "bfd.h"
/* Remove self from snmp list without walking the list*/
list_delete_node(adj->circuit->snmp_adj_list, adj->snmp_list_node);
- THREAD_OFF(adj->t_expire);
+ EVENT_OFF(adj->t_expire);
if (adj->adj_state != ISIS_ADJ_DOWN)
adj->adj_state = ISIS_ADJ_DOWN;
adj->flaps++;
if (level == IS_LEVEL_1) {
- thread_add_timer(master, send_l1_csnp,
- circuit, 0,
- &circuit->t_send_csnp[0]);
+ event_add_timer(
+ master, send_l1_csnp, circuit,
+ 0, &circuit->t_send_csnp[0]);
} else {
- thread_add_timer(master, send_l2_csnp,
- circuit, 0,
- &circuit->t_send_csnp[1]);
+ event_add_timer(
+ master, send_l2_csnp, circuit,
+ 0, &circuit->t_send_csnp[1]);
}
} else if (old_state == ISIS_ADJ_UP) {
circuit->upadjcount[level - 1]--;
assert(!"Reached end of function where we are not expecting to");
}
-void isis_adj_expire(struct thread *thread)
+void isis_adj_expire(struct event *thread)
{
struct isis_adjacency *adj;
/*
* Get the adjacency
*/
- adj = THREAD_ARG(thread);
+ adj = EVENT_ARG(thread);
assert(adj);
adj->t_expire = NULL;
enum isis_threeway_state threeway_state;
uint32_t ext_circuit_id;
int flaps; /* number of adjacency flaps */
- struct thread *t_expire; /* expire after hold_time */
+ struct event *t_expire; /* expire after hold_time */
struct isis_circuit *circuit; /* back pointer */
uint16_t *mt_set; /* Topologies this adjacency is valid for */
unsigned int mt_count; /* Number of entries in mt_set */
enum isis_adj_state state, const char *reason);
void isis_adj_print(struct isis_adjacency *adj);
const char *isis_adj_yang_state(enum isis_adj_state state);
-void isis_adj_expire(struct thread *thread);
+void isis_adj_expire(struct event *thread);
void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
char detail);
void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
void isis_adj_build_neigh_list(struct list *adjdb, struct list *list);
void isis_adj_build_up_list(struct list *adjdb, struct list *list);
int isis_adj_usage2levels(enum isis_adj_usage usage);
-void isis_bfd_startup_timer(struct thread *thread);
+void isis_bfd_startup_timer(struct event *thread);
const char *isis_adj_name(const struct isis_adjacency *adj);
#endif /* ISIS_ADJACENCY_H */
return 0;
}
-void isis_bfd_init(struct thread_master *tm)
+void isis_bfd_init(struct event_loop *tm)
{
bfd_protocol_integration_init(zclient, tm);
#define ISIS_BFD_H
struct isis_circuit;
-struct thread_master;
+struct event_loop;
void isis_bfd_circuit_cmd(struct isis_circuit *circuit);
-void isis_bfd_init(struct thread_master *tm);
+void isis_bfd_init(struct event_loop *tm);
#endif
#include "if.h"
#include "linklist.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "hash.h"
#include "prefix.h"
void isis_circuit_prepare(struct isis_circuit *circuit)
{
#if ISIS_METHOD != ISIS_METHOD_DLPI
- thread_add_read(master, isis_receive, circuit, circuit->fd,
- &circuit->t_read);
+ event_add_read(master, isis_receive, circuit, circuit->fd,
+ &circuit->t_read);
#else
- thread_add_timer_msec(master, isis_receive, circuit,
- listcount(circuit->area->circuit_list) * 100,
- &circuit->t_read);
+ event_add_timer_msec(master, isis_receive, circuit,
+ listcount(circuit->area->circuit_list) * 100,
+ &circuit->t_read);
#endif
}
send_hello_sched(circuit, level, TRIGGERED_IIH_DELAY);
circuit->u.bc.lan_neighs[level - 1] = list_new();
- thread_add_timer(master, isis_run_dr,
- &circuit->level_arg[level - 1],
- 2 * circuit->hello_interval[level - 1],
- &circuit->u.bc.t_run_dr[level - 1]);
+ event_add_timer(master, isis_run_dr,
+ &circuit->level_arg[level - 1],
+ 2 * circuit->hello_interval[level - 1],
+ &circuit->u.bc.t_run_dr[level - 1]);
}
/* 8.4.1 b) FIXME: solicit ES - 8.4.6 */
/* initializing PSNP timers */
if (circuit->is_type & IS_LEVEL_1)
- thread_add_timer(
+ event_add_timer(
master, send_l1_psnp, circuit,
isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
&circuit->t_send_psnp[0]);
if (circuit->is_type & IS_LEVEL_2)
- thread_add_timer(
+ event_add_timer(
master, send_l2_psnp, circuit,
isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
&circuit->t_send_psnp[1]);
memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
memset(circuit->u.bc.snpa, 0, ETH_ALEN);
- THREAD_OFF(circuit->u.bc.t_send_lan_hello[0]);
- THREAD_OFF(circuit->u.bc.t_send_lan_hello[1]);
- THREAD_OFF(circuit->u.bc.t_run_dr[0]);
- THREAD_OFF(circuit->u.bc.t_run_dr[1]);
- THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]);
- THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]);
+ EVENT_OFF(circuit->u.bc.t_send_lan_hello[0]);
+ EVENT_OFF(circuit->u.bc.t_send_lan_hello[1]);
+ EVENT_OFF(circuit->u.bc.t_run_dr[0]);
+ EVENT_OFF(circuit->u.bc.t_run_dr[1]);
+ EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]);
+ EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]);
circuit->lsp_regenerate_pending[0] = 0;
circuit->lsp_regenerate_pending[1] = 0;
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
isis_delete_adj(circuit->u.p2p.neighbor);
circuit->u.p2p.neighbor = NULL;
- THREAD_OFF(circuit->u.p2p.t_send_p2p_hello);
+ EVENT_OFF(circuit->u.p2p.t_send_p2p_hello);
}
/*
circuit->snmp_adj_idx_gen = 0;
/* Cancel all active threads */
- THREAD_OFF(circuit->t_send_csnp[0]);
- THREAD_OFF(circuit->t_send_csnp[1]);
- THREAD_OFF(circuit->t_send_psnp[0]);
- THREAD_OFF(circuit->t_send_psnp[1]);
- THREAD_OFF(circuit->t_read);
+ EVENT_OFF(circuit->t_send_csnp[0]);
+ EVENT_OFF(circuit->t_send_csnp[1]);
+ EVENT_OFF(circuit->t_send_psnp[0]);
+ EVENT_OFF(circuit->t_send_psnp[1]);
+ EVENT_OFF(circuit->t_read);
if (circuit->tx_queue) {
isis_tx_queue_free(circuit->tx_queue);
circuit->snd_stream = NULL;
}
- thread_cancel_event(master, circuit);
+ event_cancel_event(master, circuit);
return;
}
struct isis_bcast_info {
uint8_t snpa[ETH_ALEN]; /* SNPA of this circuit */
char run_dr_elect[ISIS_LEVELS]; /* Should we run dr election ? */
- struct thread *t_run_dr[ISIS_LEVELS]; /* DR election thread */
- struct thread *t_send_lan_hello[ISIS_LEVELS]; /* send LAN IIHs in this
- thread */
+ struct event *t_run_dr[ISIS_LEVELS]; /* DR election thread */
+ struct event *t_send_lan_hello[ISIS_LEVELS]; /* send LAN IIHs in this
+ thread */
struct list *adjdb[ISIS_LEVELS]; /* adjacency dbs */
struct list *lan_neighs[ISIS_LEVELS]; /* list of lx neigh snpa */
char is_dr[ISIS_LEVELS]; /* Are we level x DR ? */
uint8_t l1_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-1 DR */
uint8_t l2_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-2 DR */
- struct thread *t_refresh_pseudo_lsp[ISIS_LEVELS]; /* refresh pseudo-node
+ struct event *t_refresh_pseudo_lsp[ISIS_LEVELS]; /* refresh pseudo-node
LSPs */
};
struct isis_p2p_info {
struct isis_adjacency *neighbor;
- struct thread *t_send_p2p_hello; /* send P2P IIHs in this thread */
+ struct event *t_send_p2p_hello; /* send P2P IIHs in this thread */
};
struct isis_circuit_arg {
/*
* Threads
*/
- struct thread *t_read;
- struct thread *t_send_csnp[ISIS_LEVELS];
- struct thread *t_send_psnp[ISIS_LEVELS];
+ struct event *t_read;
+ struct event *t_send_csnp[ISIS_LEVELS];
+ struct event *t_send_psnp[ISIS_LEVELS];
struct isis_tx_queue *tx_queue;
struct isis_circuit_arg
level_arg[ISIS_LEVELS]; /* used as argument for threads */
#include "if.h"
#include "linklist.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "prefix.h"
#include "stream.h"
#include "log.h"
#include "hash.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "stream.h"
return NULL; /* not reached */
}
-void isis_run_dr(struct thread *thread)
+void isis_run_dr(struct event *thread)
{
- struct isis_circuit_arg *arg = THREAD_ARG(thread);
+ struct isis_circuit_arg *arg = EVENT_ARG(thread);
assert(arg);
circuit->u.bc.is_dr[level - 1] = 0;
circuit->u.bc.run_dr_elect[level - 1] = 0;
- THREAD_OFF(circuit->u.bc.t_run_dr[level - 1]);
- THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+ EVENT_OFF(circuit->u.bc.t_run_dr[level - 1]);
+ EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
circuit->lsp_regenerate_pending[level - 1] = 0;
memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN);
if (level == 1) {
memset(circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
- thread_add_timer(master, send_l1_psnp, circuit,
- isis_jitter(circuit->psnp_interval[level - 1],
- PSNP_JITTER),
- &circuit->t_send_psnp[0]);
+ event_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[level - 1],
+ PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
} else {
memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
- thread_add_timer(master, send_l2_psnp, circuit,
- isis_jitter(circuit->psnp_interval[level - 1],
- PSNP_JITTER),
- &circuit->t_send_psnp[1]);
+ event_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[level - 1],
+ PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
}
- THREAD_OFF(circuit->t_send_csnp[level - 1]);
+ EVENT_OFF(circuit->t_send_csnp[level - 1]);
- thread_add_timer(master, isis_run_dr,
- &circuit->level_arg[level - 1],
- 2 * circuit->hello_interval[level - 1],
- &circuit->u.bc.t_run_dr[level - 1]);
+ event_add_timer(master, isis_run_dr, &circuit->level_arg[level - 1],
+ 2 * circuit->hello_interval[level - 1],
+ &circuit->u.bc.t_run_dr[level - 1]);
- thread_add_event(master, isis_event_dis_status_change, circuit, 0,
- NULL);
+ event_add_event(master, isis_event_dis_status_change, circuit, 0, NULL);
return ISIS_OK;
}
assert(circuit->circuit_id); /* must be non-zero */
lsp_generate_pseudo(circuit, 1);
- thread_add_timer(master, send_l1_csnp, circuit,
- isis_jitter(circuit->csnp_interval[level - 1],
- CSNP_JITTER),
- &circuit->t_send_csnp[0]);
+ event_add_timer(master, send_l1_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[level - 1],
+ CSNP_JITTER),
+ &circuit->t_send_csnp[0]);
} else {
memcpy(old_dr, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
assert(circuit->circuit_id); /* must be non-zero */
lsp_generate_pseudo(circuit, 2);
- thread_add_timer(master, send_l2_csnp, circuit,
- isis_jitter(circuit->csnp_interval[level - 1],
- CSNP_JITTER),
- &circuit->t_send_csnp[1]);
+ event_add_timer(master, send_l2_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[level - 1],
+ CSNP_JITTER),
+ &circuit->t_send_csnp[1]);
}
- thread_add_timer(master, isis_run_dr,
- &circuit->level_arg[level - 1],
- 2 * circuit->hello_interval[level - 1],
- &circuit->u.bc.t_run_dr[level - 1]);
- thread_add_event(master, isis_event_dis_status_change, circuit, 0,
- NULL);
+ event_add_timer(master, isis_run_dr, &circuit->level_arg[level - 1],
+ 2 * circuit->hello_interval[level - 1],
+ &circuit->u.bc.t_run_dr[level - 1]);
+ event_add_event(master, isis_event_dis_status_change, circuit, 0, NULL);
return ISIS_OK;
}
#ifndef _ZEBRA_ISIS_DR_H
#define _ZEBRA_ISIS_DR_H
-void isis_run_dr(struct thread *thread);
+void isis_run_dr(struct event *thread);
int isis_dr_elect(struct isis_circuit *circuit, int level);
int isis_dr_resign(struct isis_circuit *circuit, int level);
int isis_dr_commence(struct isis_circuit *circuit, int level);
#include "stream.h"
#include "command.h"
#include "if.h"
-#include "thread.h"
+#include "frrevent.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_DYNHN, "ISIS dyn hostname");
-static void dyn_cache_cleanup(struct thread *);
+static void dyn_cache_cleanup(struct event *);
void dyn_cache_init(struct isis *isis)
{
isis->dyn_cache = list_new();
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
- thread_add_timer(master, dyn_cache_cleanup, isis, 120,
- &isis->t_dync_clean);
+ event_add_timer(master, dyn_cache_cleanup, isis, 120,
+ &isis->t_dync_clean);
}
void dyn_cache_finish(struct isis *isis)
struct listnode *node, *nnode;
struct isis_dynhn *dyn;
- THREAD_OFF(isis->t_dync_clean);
+ EVENT_OFF(isis->t_dync_clean);
for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
list_delete_node(isis->dyn_cache, node);
list_delete(&isis->dyn_cache);
}
-static void dyn_cache_cleanup(struct thread *thread)
+static void dyn_cache_cleanup(struct event *thread)
{
struct listnode *node, *nnode;
struct isis_dynhn *dyn;
time_t now = time(NULL);
struct isis *isis = NULL;
- isis = THREAD_ARG(thread);
+ isis = EVENT_ARG(thread);
isis->t_dync_clean = NULL;
XFREE(MTYPE_ISIS_DYNHN, dyn);
}
- thread_add_timer(master, dyn_cache_cleanup, isis, 120,
+ event_add_timer(master, dyn_cache_cleanup, isis, 120,
&isis->t_dync_clean);
}
#include "if.h"
#include "linklist.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "prefix.h"
#include "stream.h"
if (!circuit->is_passive) {
if (level == 1) {
- thread_add_timer(master, send_l1_psnp, circuit,
- isis_jitter(circuit->psnp_interval[0],
- PSNP_JITTER),
- &circuit->t_send_psnp[0]);
+ event_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[0],
+ PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
} else {
- thread_add_timer(master, send_l2_psnp, circuit,
- isis_jitter(circuit->psnp_interval[1],
- PSNP_JITTER),
- &circuit->t_send_psnp[1]);
+ event_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[1],
+ PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
}
}
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
- thread_add_timer(master, isis_run_dr,
- &circuit->level_arg[level - 1],
- 2 * circuit->hello_interval[level - 1],
- &circuit->u.bc.t_run_dr[level - 1]);
+ event_add_timer(master, isis_run_dr,
+ &circuit->level_arg[level - 1],
+ 2 * circuit->hello_interval[level - 1],
+ &circuit->u.bc.t_run_dr[level - 1]);
send_hello_sched(circuit, level, TRIGGERED_IIH_DELAY);
circuit->u.bc.lan_neighs[level - 1] = list_new();
circuit->area->area_tag, circuit->circuit_id,
circuit->interface->name, level);
- THREAD_OFF(circuit->t_send_csnp[idx]);
- THREAD_OFF(circuit->t_send_psnp[idx]);
+ EVENT_OFF(circuit->t_send_csnp[idx]);
+ EVENT_OFF(circuit->t_send_psnp[idx]);
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
- THREAD_OFF(circuit->u.bc.t_send_lan_hello[idx]);
- THREAD_OFF(circuit->u.bc.t_run_dr[idx]);
- THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]);
+ EVENT_OFF(circuit->u.bc.t_send_lan_hello[idx]);
+ EVENT_OFF(circuit->u.bc.t_run_dr[idx]);
+ EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]);
circuit->lsp_regenerate_pending[idx] = 0;
circuit->u.bc.run_dr_elect[idx] = 0;
circuit->u.bc.is_dr[idx] = 0;
/* events supporting code */
-void isis_event_dis_status_change(struct thread *thread)
+void isis_event_dis_status_change(struct event *thread)
{
struct isis_circuit *circuit;
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
/* invalid arguments */
if (!circuit || !circuit->area)
/*
* Events related to adjacencies
*/
-void isis_event_dis_status_change(struct thread *thread);
+void isis_event_dis_status_change(struct event *thread);
/*
* Error events
#include "monotime.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "table.h"
#include "vty.h"
if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP)
ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP;
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
isis_ldp_sync_set_if_metric(circuit, true);
}
if (ldp_sync_info &&
ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED &&
ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) {
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
isis_ldp_sync_set_if_metric(circuit, true);
}
/*
* LDP-SYNC holddown timer routines
*/
-static void isis_ldp_sync_holddown_timer(struct thread *thread)
+static void isis_ldp_sync_holddown_timer(struct event *thread)
{
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
* didn't receive msg from LDP indicating sync-complete
* restore interface cost to original value
*/
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
if (circuit->ldp_sync_info == NULL)
return;
ils_debug("%s: start holddown timer for %s time %d", __func__,
circuit->interface->name, ldp_sync_info->holddown);
- thread_add_timer(master, isis_ldp_sync_holddown_timer,
- circuit, ldp_sync_info->holddown,
- &ldp_sync_info->t_holddown);
+ event_add_timer(master, isis_ldp_sync_holddown_timer, circuit,
+ ldp_sync_info->holddown, &ldp_sync_info->t_holddown);
}
/*
if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
return;
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
isis_ldp_sync_set_if_metric(circuit, true);
}
break;
case LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP:
if (ldp_sync_info->t_holddown != NULL) {
- struct timeval remain = thread_timer_remain(
- ldp_sync_info->t_holddown);
+ struct timeval remain =
+ event_timer_remain(ldp_sync_info->t_holddown);
vty_out(vty,
" Holddown timer is running %lld.%03lld remaining\n",
(long long)remain.tv_sec,
return rlfa_tree_find(&spftree->lfa.remote.rlfas, &s);
}
-static void isis_area_verify_routes_cb(struct thread *thread)
+static void isis_area_verify_routes_cb(struct event *thread)
{
- struct isis_area *area = THREAD_ARG(thread);
+ struct isis_area *area = EVENT_ARG(thread);
if (IS_DEBUG_LFA)
zlog_debug("ISIS-LFA: updating RLFAs in the RIB");
spftree->route_table_backup);
spftree->lfa.protection_counters.rlfa[vertex->N.ip.priority] += 1;
- THREAD_OFF(area->t_rlfa_rib_update);
- thread_add_timer(master, isis_area_verify_routes_cb, area, 2,
- &area->t_rlfa_rib_update);
+ EVENT_OFF(area->t_rlfa_rib_update);
+ event_add_timer(master, isis_area_verify_routes_cb, area, 2,
+ &area->t_rlfa_rib_update);
return 0;
}
isis_route_delete(area, rn, spftree->route_table_backup);
spftree->lfa.protection_counters.rlfa[vertex->N.ip.priority] -= 1;
- THREAD_OFF(area->t_rlfa_rib_update);
- thread_add_timer(master, isis_area_verify_routes_cb, area, 2,
- &area->t_rlfa_rib_update);
+ EVENT_OFF(area->t_rlfa_rib_update);
+ event_add_timer(master, isis_area_verify_routes_cb, area, 2,
+ &area->t_rlfa_rib_update);
}
void isis_rlfa_list_init(struct isis_spftree *spftree)
#include <zebra.h>
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "stream.h"
#include "memory.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_LSP, "ISIS LSP");
-static void lsp_refresh(struct thread *thread);
-static void lsp_l1_refresh_pseudo(struct thread *thread);
-static void lsp_l2_refresh_pseudo(struct thread *thread);
+static void lsp_refresh(struct event *thread);
+static void lsp_l1_refresh_pseudo(struct event *thread);
+static void lsp_l2_refresh_pseudo(struct event *thread);
static void lsp_destroy(struct isis_lsp *lsp);
/*
* Unset the overload bit after the timer expires
*/
-void set_overload_on_start_timer(struct thread *thread)
+void set_overload_on_start_timer(struct event *thread)
{
- struct isis_area *area = THREAD_ARG(thread);
+ struct isis_area *area = EVENT_ARG(thread);
assert(area);
area->t_overload_on_startup_timer = NULL;
return ISIS_ERROR;
/* Check if config is still being processed */
- if (thread_is_scheduled(t_isis_cfg))
+ if (event_is_scheduled(t_isis_cfg))
return ISIS_OK;
memset(&lspid, 0, ISIS_SYS_ID_LEN + 2);
overload_time = isis_restart_read_overload_time(area);
if (overload_time > 0) {
isis_area_overload_bit_set(area, true);
- thread_add_timer(master, set_overload_on_start_timer,
- area, overload_time,
- &area->t_overload_on_startup_timer);
+ event_add_timer(master, set_overload_on_start_timer,
+ area, overload_time,
+ &area->t_overload_on_startup_timer);
}
device_startup = false;
}
refresh_time = lsp_refresh_time(newlsp, rem_lifetime);
- THREAD_OFF(area->t_lsp_refresh[level - 1]);
+ EVENT_OFF(area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
- thread_add_timer(master, lsp_refresh,
- &area->lsp_refresh_arg[level - 1], refresh_time,
- &area->t_lsp_refresh[level - 1]);
+ event_add_timer(master, lsp_refresh, &area->lsp_refresh_arg[level - 1],
+ refresh_time, &area->t_lsp_refresh[level - 1]);
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug("ISIS-Upd (%s): Building L%d LSP %s, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus refresh %hus",
lsp_seqno_update(lsp);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
- thread_add_timer(master, lsp_refresh,
- &area->lsp_refresh_arg[level - 1], refresh_time,
- &area->t_lsp_refresh[level - 1]);
+ event_add_timer(master, lsp_refresh, &area->lsp_refresh_arg[level - 1],
+ refresh_time, &area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
if (IS_DEBUG_UPDATE_PACKETS) {
/*
* Something has changed or periodic refresh -> regenerate LSP
*/
-static void lsp_refresh(struct thread *thread)
+static void lsp_refresh(struct event *thread)
{
- struct lsp_refresh_arg *arg = THREAD_ARG(thread);
+ struct lsp_refresh_arg *arg = EVENT_ARG(thread);
assert(arg);
* Note: in case of a BFD 'down' message the refresh is
* scheduled once again just to be sure
*/
- struct timeval remain = thread_timer_remain(
+ struct timeval remain = event_timer_remain(
area->t_lsp_refresh[lvl - 1]);
sched_debug(
"ISIS (%s): Regeneration is already pending, nothing todo. (Due in %lld.%03lld seconds)",
"ISIS (%s): Will schedule regen timer. Last run was: %lld, Now is: %lld",
area->area_tag, (long long)lsp->last_generated,
(long long)now);
- THREAD_OFF(area->t_lsp_refresh[lvl - 1]);
+ EVENT_OFF(area->t_lsp_refresh[lvl - 1]);
diff = now - lsp->last_generated;
if (diff < area->lsp_gen_interval[lvl - 1]
&& !(area->bfd_signalled_down)) {
}
area->lsp_regenerate_pending[lvl - 1] = 1;
- thread_add_timer_msec(master, lsp_refresh,
- &area->lsp_refresh_arg[lvl - 1],
- timeout,
- &area->t_lsp_refresh[lvl - 1]);
+ event_add_timer_msec(master, lsp_refresh,
+ &area->lsp_refresh_arg[lvl - 1], timeout,
+ &area->t_lsp_refresh[lvl - 1]);
}
if (all_pseudo) {
lsp_flood(lsp, NULL);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
- THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+ EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
circuit->lsp_regenerate_pending[level - 1] = 0;
if (level == IS_LEVEL_1)
- thread_add_timer(
- master, lsp_l1_refresh_pseudo, circuit, refresh_time,
- &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+ event_add_timer(master, lsp_l1_refresh_pseudo, circuit,
+ refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
else if (level == IS_LEVEL_2)
- thread_add_timer(
- master, lsp_l2_refresh_pseudo, circuit, refresh_time,
- &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+ event_add_timer(master, lsp_l2_refresh_pseudo, circuit,
+ refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug(
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
if (level == IS_LEVEL_1)
- thread_add_timer(
- master, lsp_l1_refresh_pseudo, circuit, refresh_time,
- &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+ event_add_timer(master, lsp_l1_refresh_pseudo, circuit,
+ refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
else if (level == IS_LEVEL_2)
- thread_add_timer(
- master, lsp_l2_refresh_pseudo, circuit, refresh_time,
- &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+ event_add_timer(master, lsp_l2_refresh_pseudo, circuit,
+ refresh_time,
+ &circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug(
/*
* Something has changed or periodic refresh -> regenerate pseudo LSP
*/
-static void lsp_l1_refresh_pseudo(struct thread *thread)
+static void lsp_l1_refresh_pseudo(struct event *thread)
{
struct isis_circuit *circuit;
uint8_t id[ISIS_SYS_ID_LEN + 2];
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
circuit->u.bc.t_refresh_pseudo_lsp[0] = NULL;
circuit->lsp_regenerate_pending[0] = 0;
lsp_regenerate_pseudo(circuit, IS_LEVEL_1);
}
-static void lsp_l2_refresh_pseudo(struct thread *thread)
+static void lsp_l2_refresh_pseudo(struct event *thread)
{
struct isis_circuit *circuit;
uint8_t id[ISIS_SYS_ID_LEN + 2];
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
circuit->u.bc.t_refresh_pseudo_lsp[1] = NULL;
circuit->lsp_regenerate_pending[1] = 0;
}
if (circuit->lsp_regenerate_pending[lvl - 1]) {
- struct timeval remain = thread_timer_remain(
+ struct timeval remain = event_timer_remain(
circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
sched_debug(
"ISIS (%s): Regenerate is already pending, nothing todo. (Due in %lld.%03lld seconds)",
"ISIS (%s): Will schedule PSN regen timer. Last run was: %lld, Now is: %lld",
area->area_tag, (long long)lsp->last_generated,
(long long)now);
- THREAD_OFF(circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
+ EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
diff = now - lsp->last_generated;
if (diff < circuit->area->lsp_gen_interval[lvl - 1]) {
timeout =
circuit->lsp_regenerate_pending[lvl - 1] = 1;
if (lvl == IS_LEVEL_1) {
- thread_add_timer_msec(
+ event_add_timer_msec(
master, lsp_l1_refresh_pseudo, circuit, timeout,
&circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
} else if (lvl == IS_LEVEL_2) {
- thread_add_timer_msec(
+ event_add_timer_msec(
master, lsp_l2_refresh_pseudo, circuit, timeout,
&circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
}
* Walk through LSPs for an area
* - set remaining lifetime
*/
-void lsp_tick(struct thread *thread)
+void lsp_tick(struct event *thread)
{
struct isis_area *area;
struct isis_lsp *lsp;
uint16_t rem_lifetime;
bool fabricd_sync_incomplete = false;
- area = THREAD_ARG(thread);
+ area = EVENT_ARG(thread);
assert(area);
area->t_tick = NULL;
- thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
+ event_add_timer(master, lsp_tick, area, 1, &area->t_tick);
struct isis_circuit *fabricd_init_c = fabricd_initial_sync_circuit(area);
void lsp_db_init(struct lspdb_head *head);
void lsp_db_fini(struct lspdb_head *head);
-void lsp_tick(struct thread *thread);
-void set_overload_on_start_timer(struct thread *thread);
+void lsp_tick(struct event *thread);
+void set_overload_on_start_timer(struct event *thread);
int lsp_generate(struct isis_area *area, int level);
#define lsp_regenerate_schedule(area, level, all_pseudo) \
#include <zebra.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include <lib/version.h>
#include "command.h"
{0}};
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/*
* Prototypes.
/* clang-format on */
-static void isis_config_finish(struct thread *t)
+static void isis_config_finish(struct event *t)
{
struct listnode *node, *inode;
struct isis *isis;
{
/* Max wait time for config to load before generating lsp */
#define ISIS_PRE_CONFIG_MAX_WAIT_SECONDS 600
- THREAD_OFF(t_isis_cfg);
- thread_add_timer(im->master, isis_config_finish, NULL,
- ISIS_PRE_CONFIG_MAX_WAIT_SECONDS, &t_isis_cfg);
+ EVENT_OFF(t_isis_cfg);
+ event_add_timer(im->master, isis_config_finish, NULL,
+ ISIS_PRE_CONFIG_MAX_WAIT_SECONDS, &t_isis_cfg);
}
static void isis_config_end(void)
/* If ISIS config processing thread isn't running, then
* we can return and rely it's properly handled.
*/
- if (!thread_is_scheduled(t_isis_cfg))
+ if (!event_is_scheduled(t_isis_cfg))
return;
- THREAD_OFF(t_isis_cfg);
+ EVENT_OFF(t_isis_cfg);
isis_config_finish(t_isis_cfg);
}
#include <zebra.h>
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "log.h"
#include "stream.h"
adj);
/* lets take care of the expiry */
- THREAD_OFF(adj->t_expire);
- thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
- &adj->t_expire);
+ EVENT_OFF(adj->t_expire);
+ event_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
+ &adj->t_expire);
/* While fabricds initial sync is in progress, ignore hellos from other
* interfaces than the one we are performing the initial sync on. */
: iih->circuit->u.bc.l2_desig_is;
if (memcmp(dis, iih->dis, ISIS_SYS_ID_LEN + 1)) {
- thread_add_event(master, isis_event_dis_status_change,
- iih->circuit, 0, NULL);
+ event_add_event(master, isis_event_dis_status_change,
+ iih->circuit, 0, NULL);
memcpy(dis, iih->dis, ISIS_SYS_ID_LEN + 1);
}
}
adj);
/* lets take care of the expiry */
- THREAD_OFF(adj->t_expire);
- thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
- &adj->t_expire);
+ EVENT_OFF(adj->t_expire);
+ event_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
+ &adj->t_expire);
/*
* If the snpa for this circuit is found from LAN Neighbours TLV
if (idrp == ISO9542_ESIS) {
flog_err(EC_LIB_DEVELOPMENT,
"No support for ES-IS packet IDRP=%hhx", idrp);
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
if (idrp != ISO10589_ISIS) {
flog_err(EC_ISIS_PACKET, "Not an IS-IS packet IDRP=%hhx",
idrp);
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
isis_notif_version_skew(circuit, version1, raw_pdu,
sizeof(raw_pdu));
#endif /* ifndef FABRICD */
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_WARNING;
}
isis_notif_id_len_mismatch(circuit, id_len, raw_pdu,
sizeof(raw_pdu));
#endif /* ifndef FABRICD */
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
uint8_t expected_length;
if (pdu_size(pdu_type, &expected_length)) {
zlog_warn("Unsupported ISIS PDU %hhu", pdu_type);
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_WARNING;
}
flog_err(EC_ISIS_PACKET,
"Expected fixed header length = %hhu but got %hhu",
expected_length, length);
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
flog_err(
EC_ISIS_PACKET,
"PDU is too short to contain fixed header of given PDU type.");
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
isis_notif_version_skew(circuit, version2, raw_pdu,
sizeof(raw_pdu));
#endif /* ifndef FABRICD */
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_WARNING;
}
if (circuit->is_passive) {
zlog_warn("Received ISIS PDU on passive circuit %s",
circuit->interface->name);
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_WARNING;
}
isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
raw_pdu, sizeof(raw_pdu));
#endif /* ifndef FABRICD */
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
case L1_LAN_HELLO:
case L2_LAN_HELLO:
case P2P_HELLO:
- if (fabricd && pdu_type != P2P_HELLO)
+ if (fabricd && pdu_type != P2P_HELLO) {
+ pdu_counter_count(circuit->area->pdu_drop_counters,
+ pdu_type);
return ISIS_ERROR;
+ }
+
retval = process_hello(pdu_type, circuit, ssnpa);
break;
case L1_LINK_STATE:
case L2_LINK_STATE:
case FS_LINK_STATE:
- if (fabricd
- && pdu_type != L2_LINK_STATE
- && pdu_type != FS_LINK_STATE)
+ if (fabricd && pdu_type != L2_LINK_STATE &&
+ pdu_type != FS_LINK_STATE) {
+ pdu_counter_count(circuit->area->pdu_drop_counters,
+ pdu_type);
return ISIS_ERROR;
+ }
+
retval = process_lsp(pdu_type, circuit, ssnpa, max_area_addrs);
break;
case L1_COMPLETE_SEQ_NUM:
retval = process_snp(pdu_type, circuit, ssnpa);
break;
default:
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
return ISIS_ERROR;
}
+ if (retval != ISIS_OK)
+ pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+
return retval;
}
-void isis_receive(struct thread *thread)
+void isis_receive(struct event *thread)
{
struct isis_circuit *circuit;
uint8_t ssnpa[ETH_ALEN];
/*
* Get the circuit
*/
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
assert(circuit);
circuit->t_read = NULL;
return retval;
}
-static void send_hello_cb(struct thread *thread)
+static void send_hello_cb(struct event *thread)
{
- struct isis_circuit_arg *arg = THREAD_ARG(thread);
+ struct isis_circuit_arg *arg = EVENT_ARG(thread);
assert(arg);
struct isis_circuit *circuit = arg->circuit;
}
static void _send_hello_sched(struct isis_circuit *circuit,
- struct thread **threadp,
- int level, long delay)
+ struct event **threadp, int level, long delay)
{
if (*threadp) {
- if (thread_timer_remain_msec(*threadp) < (unsigned long)delay)
+ if (event_timer_remain_msec(*threadp) < (unsigned long)delay)
return;
- THREAD_OFF(*threadp);
+ EVENT_OFF(*threadp);
}
- thread_add_timer_msec(master, send_hello_cb,
- &circuit->level_arg[level - 1],
- isis_jitter(delay, IIH_JITTER),
- threadp);
+ event_add_timer_msec(master, send_hello_cb,
+ &circuit->level_arg[level - 1],
+ isis_jitter(delay, IIH_JITTER), threadp);
}
void send_hello_sched(struct isis_circuit *circuit, int level, long delay)
return ISIS_OK;
}
-void send_l1_csnp(struct thread *thread)
+void send_l1_csnp(struct event *thread)
{
struct isis_circuit *circuit;
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
assert(circuit);
circuit->t_send_csnp[0] = NULL;
send_csnp(circuit, 1);
}
/* set next timer thread */
- thread_add_timer(master, send_l1_csnp, circuit,
- isis_jitter(circuit->csnp_interval[0], CSNP_JITTER),
- &circuit->t_send_csnp[0]);
+ event_add_timer(master, send_l1_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[0], CSNP_JITTER),
+ &circuit->t_send_csnp[0]);
}
-void send_l2_csnp(struct thread *thread)
+void send_l2_csnp(struct event *thread)
{
struct isis_circuit *circuit;
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
assert(circuit);
circuit->t_send_csnp[1] = NULL;
send_csnp(circuit, 2);
}
/* set next timer thread */
- thread_add_timer(master, send_l2_csnp, circuit,
- isis_jitter(circuit->csnp_interval[1], CSNP_JITTER),
- &circuit->t_send_csnp[1]);
+ event_add_timer(master, send_l2_csnp, circuit,
+ isis_jitter(circuit->csnp_interval[1], CSNP_JITTER),
+ &circuit->t_send_csnp[1]);
}
/*
return ISIS_OK;
}
-void send_l1_psnp(struct thread *thread)
+void send_l1_psnp(struct event *thread)
{
struct isis_circuit *circuit;
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
assert(circuit);
circuit->t_send_psnp[0] = NULL;
send_psnp(1, circuit);
/* set next timer thread */
- thread_add_timer(master, send_l1_psnp, circuit,
- isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
- &circuit->t_send_psnp[0]);
+ event_add_timer(master, send_l1_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
+ &circuit->t_send_psnp[0]);
}
/*
* 7.3.15.4 action on expiration of partial SNP interval
* level 2
*/
-void send_l2_psnp(struct thread *thread)
+void send_l2_psnp(struct event *thread)
{
struct isis_circuit *circuit;
- circuit = THREAD_ARG(thread);
+ circuit = EVENT_ARG(thread);
assert(circuit);
circuit->t_send_psnp[1] = NULL;
send_psnp(2, circuit);
/* set next timer thread */
- thread_add_timer(master, send_l2_psnp, circuit,
- isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
- &circuit->t_send_psnp[1]);
+ event_add_timer(master, send_l2_psnp, circuit,
+ isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
+ &circuit->t_send_psnp[1]);
}
/*
/*
* Function for receiving IS-IS PDUs
*/
-void isis_receive(struct thread *thread);
+void isis_receive(struct event *thread);
/*
* calling arguments for snp_process ()
*/
void send_hello_sched(struct isis_circuit *circuit, int level, long delay);
int send_csnp(struct isis_circuit *circuit, int level);
-void send_l1_csnp(struct thread *thread);
-void send_l2_csnp(struct thread *thread);
-void send_l1_psnp(struct thread *thread);
-void send_l2_psnp(struct thread *thread);
+void send_l1_csnp(struct event *thread);
+void send_l2_csnp(struct event *thread);
+void send_l1_psnp(struct event *thread);
+void send_l2_psnp(struct event *thread);
void send_lsp(struct isis_circuit *circuit,
struct isis_lsp *lsp, enum isis_tx_type tx_type);
void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "log.h"
#include "plist.h"
#include "routemap.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "isis_constants.h"
/* Declare static local variables for convenience. */
SNMP_LOCAL_VARIABLES
-/* If ARRAY_SIZE is not available use a primitive substitution */
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif
-
/*
* Define time function, it serves two purposes
* 1. Uses unint32_t for unix time and encapsulates
{isis_snmp_find_isadj_ipaddr, {ISIS_ISADJIPADDR_ENTRY}, 4},
{isis_snmp_find_isadj_prot_supp, {ISIS_ISADJPROTSUPP_ENTRY}, 4},
};
-static size_t isis_func_to_prefix_count = ARRAY_SIZE(isis_func_to_prefix_arr);
+static size_t isis_func_to_prefix_count = array_size(isis_func_to_prefix_arr);
static struct variable isis_var_arr[] = {
{ISIS_SYS_VERSION, INTEGER, RONLY, isis_snmp_find_sys_object},
isis_snmp_find_isadj_prot_supp},
};
-static const size_t isis_var_count = ARRAY_SIZE(isis_var_arr);
+static const size_t isis_var_count = array_size(isis_var_arr);
/* Minimal set of hard-coded data */
#define ISIS_VERSION (1)
/* Register ISIS-MIB. */
-static int isis_snmp_init(struct thread_master *tm)
+static int isis_snmp_init(struct event_loop *tm)
{
struct isis_func_to_prefix *h2f = isis_func_to_prefix_arr;
struct variable *v;
/* Put in trap value */
snmp_varlist_add_variable(¬ification_vars, isis_snmp_trap_var,
- ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+ array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
(uint8_t *)&isis_snmp_trap_val_db_overload,
sizeof(isis_snmp_trap_val_db_overload));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_sys_level_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+ array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
(uint8_t *)&val, sizeof(val));
/* Patch sys_level_state with proper index */
- off = ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state) - 1;
+ off = array_size(isis_snmp_trap_data_var_sys_level_state) - 1;
isis_snmp_trap_data_var_sys_level_state[off] = val;
/* Prepare data */
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_sys_level_state,
- ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_state), INTEGER,
+ array_size(isis_snmp_trap_data_var_sys_level_state), INTEGER,
(uint8_t *)&val, sizeof(val));
send_v2trap(notification_vars);
/* Put in trap value */
snmp_varlist_add_variable(¬ification_vars, isis_snmp_trap_var,
- ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+ array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
(uint8_t *)&isis_snmp_trap_val_lsp_exceed_max,
sizeof(isis_snmp_trap_val_lsp_exceed_max));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_sys_level_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+ array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
(uint8_t *)&val, sizeof(val));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_pdu_lsp_id,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
ISIS_SYS_ID_LEN + 2);
send_v2trap(notification_vars);
/* Put in trap value */
memcpy(var_name, isis_snmp_notifications,
sizeof(isis_snmp_notifications));
- var_count = ARRAY_SIZE(isis_snmp_notifications);
+ var_count = array_size(isis_snmp_notifications);
var_name[var_count++] = trap_id;
/* Put in trap value */
snmp_varlist_add_variable(¬ification_vars, isis_snmp_trap_var,
- ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+ array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
(uint8_t *)var_name, var_count * sizeof(oid));
val = circuit->is_type;
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_sys_level_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+ array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
(uint8_t *)&val, sizeof(val));
if (oid_a_len != 0) {
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_circ_if_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
(uint8_t *)&val, sizeof(val));
/* Put in trap value */
memcpy(var_name, isis_snmp_notifications,
sizeof(isis_snmp_notifications));
- var_count = ARRAY_SIZE(isis_snmp_notifications);
+ var_count = array_size(isis_snmp_notifications);
var_name[var_count++] = trap_id;
/* Put in trap value */
snmp_varlist_add_variable(¬ification_vars, isis_snmp_trap_var,
- ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+ array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
(uint8_t *)var_name, var_count * sizeof(oid));
val = circuit->is_type;
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_sys_level_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+ array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
(uint8_t *)&val, sizeof(val));
if (circuit->interface == NULL)
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_circ_if_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
(uint8_t *)&val, sizeof(val));
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_ID_LEN_MISMATCH,
isis_snmp_trap_data_var_pdu_field_len,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_field_len), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_pdu_field_len), UNSIGNED32,
&val, sizeof(val), isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
return 0;
}
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_MAX_AREA_ADDR_MISMATCH,
isis_snmp_trap_data_var_pdu_max_area_addr,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_max_area_addr),
+ array_size(isis_snmp_trap_data_var_pdu_max_area_addr),
UNSIGNED32, &val, sizeof(val),
isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
return 0;
}
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_OWN_LSP_PURGE, NULL, 0, STRING, NULL, 0,
isis_snmp_trap_data_var_pdu_lsp_id,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
ISIS_SYS_ID_LEN + 2);
return 0;
}
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_SEQNO_SKIPPED, NULL, 0, STRING, NULL, 0,
isis_snmp_trap_data_var_pdu_lsp_id,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
ISIS_SYS_ID_LEN + 2);
return 0;
}
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_AUTHEN_TYPE_FAILURE, NULL, 0, STRING, NULL,
0, isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
return 0;
}
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_AUTHEN_FAILURE, NULL, 0, STRING, NULL, 0,
isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
return 0;
}
isis_snmp_update_worker_b(
circuit, ISIS_TRAP_VERSION_SKEW,
isis_snmp_trap_data_var_pdu_proto_ver,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_proto_ver), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_pdu_proto_ver), UNSIGNED32,
&val, sizeof(val), isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
return 0;
}
/* Put in trap value */
snmp_varlist_add_variable(¬ification_vars, isis_snmp_trap_var,
- ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+ array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
(uint8_t *)&isis_snmp_trap_val_area_mismatch,
sizeof(isis_snmp_trap_val_area_mismatch));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_circ_if_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
(uint8_t *)&val, sizeof(val));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
send_v2trap(notification_vars);
isis_snmp_update_worker_a(
circuit, ISIS_TRAP_REJ_ADJACENCY, NULL, 0, STRING, NULL, 0,
isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
return 0;
}
isis_snmp_update_worker_b(
circuit, ISIS_TRAP_LSP_TOO_LARGE,
isis_snmp_trap_data_var_pdu_lsp_size,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_size), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_size), UNSIGNED32,
&pdu_size, sizeof(pdu_size), isis_snmp_trap_data_var_pdu_lsp_id,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
ISIS_SYS_ID_LEN + 2);
return 0;
}
isis_snmp_update_worker_b(
adj->circuit, ISIS_TRAP_ADJ_STATE_CHANGE,
isis_snmp_trap_data_var_pdu_lsp_id,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
ISIS_SYS_ID_LEN + 2, isis_snmp_trap_data_var_adj_state,
- ARRAY_SIZE(isis_snmp_trap_data_var_adj_state), INTEGER, &val,
+ array_size(isis_snmp_trap_data_var_adj_state), INTEGER, &val,
sizeof(val));
return 0;
}
/* Put in trap value */
snmp_varlist_add_variable(¬ification_vars, isis_snmp_trap_var,
- ARRAY_SIZE(isis_snmp_trap_var), ASN_OBJECT_ID,
+ array_size(isis_snmp_trap_var), ASN_OBJECT_ID,
(uint8_t *)&isis_snmp_trap_val_lsp_error,
sizeof(isis_snmp_trap_val_lsp_error));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_sys_level_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_sys_level_index), INTEGER,
+ array_size(isis_snmp_trap_data_var_sys_level_index), INTEGER,
(uint8_t *)&val, sizeof(val));
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_pdu_lsp_id,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
+ array_size(isis_snmp_trap_data_var_pdu_lsp_id), STRING, lsp_id,
ISIS_SYS_ID_LEN + 2);
/* Prepare data */
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_circ_if_index,
- ARRAY_SIZE(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_circ_if_index), UNSIGNED32,
(uint8_t *)&val, sizeof(val));
/* Prepare data */
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_pdu_fragment,
- ARRAY_SIZE(isis_snmp_trap_data_var_pdu_fragment), STRING,
+ array_size(isis_snmp_trap_data_var_pdu_fragment), STRING,
raw_pdu, raw_pdu_len);
/* Prepare data */
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_error_offset,
- ARRAY_SIZE(isis_snmp_trap_data_var_error_offset), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_error_offset), UNSIGNED32,
(uint8_t *)&val, sizeof(val));
/* Prepare data */
snmp_varlist_add_variable(
¬ification_vars, isis_snmp_trap_data_var_error_tlv_type,
- ARRAY_SIZE(isis_snmp_trap_data_var_error_tlv_type), UNSIGNED32,
+ array_size(isis_snmp_trap_data_var_error_tlv_type), UNSIGNED32,
(uint8_t *)&val, sizeof(val));
send_v2trap(notification_vars);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "log.h"
{
list_delete(&vertex->Adj_N);
list_delete(&vertex->parents);
- if (vertex->firsthops) {
- hash_clean(vertex->firsthops, NULL);
- hash_free(vertex->firsthops);
- vertex->firsthops = NULL;
- }
+ hash_clean_and_free(&vertex->firsthops, NULL);
memset(vertex, 0, sizeof(struct isis_vertex));
XFREE(MTYPE_ISIS_VERTEX, vertex);
void isis_spftree_del(struct isis_spftree *spftree)
{
- hash_clean(spftree->prefix_sids, NULL);
- hash_free(spftree->prefix_sids);
+ hash_clean_and_free(&spftree->prefix_sids, NULL);
isis_zebra_rlfa_unregister_all(spftree);
isis_rlfa_list_clear(spftree);
list_delete(&spftree->lfa.remote.pc_spftrees);
family, nexthop_ip, ifindex);
}
-static void isis_run_spf_cb(struct thread *thread)
+static void isis_run_spf_cb(struct event *thread)
{
- struct isis_spf_run *run = THREAD_ARG(thread);
+ struct isis_spf_run *run = EVENT_ARG(thread);
struct isis_area *area = run->area;
int level = run->level;
int have_run = 0;
area->area_tag, level, diff, func, file, line);
}
- THREAD_OFF(area->t_rlfa_rib_update);
+ EVENT_OFF(area->t_rlfa_rib_update);
if (area->spf_delay_ietf[level - 1]) {
/* Need to call schedule function also if spf delay is running
* to
if (area->spf_timer[level - 1])
return ISIS_OK;
- thread_add_timer_msec(master, isis_run_spf_cb,
- isis_run_spf_arg(area, level), delay,
- &area->spf_timer[level - 1]);
+ event_add_timer_msec(master, isis_run_spf_cb,
+ isis_run_spf_arg(area, level), delay,
+ &area->spf_timer[level - 1]);
return ISIS_OK;
}
timer = area->min_spf_interval[level - 1] - diff;
}
- thread_add_timer(master, isis_run_spf_cb, isis_run_spf_arg(area, level),
- timer, &area->spf_timer[level - 1]);
+ event_add_timer(master, isis_run_spf_cb, isis_run_spf_arg(area, level),
+ timer, &area->spf_timer[level - 1]);
if (IS_DEBUG_SPF_EVENTS)
zlog_debug("ISIS-SPF (%s) L%d SPF scheduled %ld sec from now",
*
* @return 1 on success
*/
-static void sr_start_label_manager(struct thread *start)
+static void sr_start_label_manager(struct event *start)
{
struct isis_area *area;
- area = THREAD_ARG(start);
+ area = EVENT_ARG(start);
/* re-attempt to start SR & Label Manager connection */
isis_sr_start(area);
if (!isis_zebra_label_manager_ready())
if (isis_zebra_label_manager_connect() < 0) {
/* Re-attempt to connect to Label Manager in 1 sec. */
- thread_add_timer(master, sr_start_label_manager, area,
- 1, &srdb->t_start_lm);
+ event_add_timer(master, sr_start_label_manager, area, 1,
+ &srdb->t_start_lm);
return -1;
}
area->area_tag);
/* Disable any re-attempt to connect to Label Manager */
- THREAD_OFF(srdb->t_start_lm);
+ EVENT_OFF(srdb->t_start_lm);
/* Uninstall all local Adjacency-SIDs. */
for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra))
bool enabled;
/* Thread timer to start Label Manager */
- struct thread *t_start_lm;
+ struct event *t_start_lm;
/* List of local Adjacency-SIDs. */
struct list *adj_sids;
#include <math.h>
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "stream.h"
#include "memory.h"
}
if (!std)
prefix_copy(&p, prefix);
- else
+ else {
+ /* Remove old subnet if any before prefix adjustment */
+ subnet = ls_find_subnet(args->ted, *prefix);
+ if (subnet) {
+ if (args->export) {
+ subnet->status = DELETE;
+ isis_te_export(LS_MSG_TYPE_PREFIX, subnet);
+ }
+ te_debug(" |- Remove subnet with prefix %pFX",
+ &subnet->key);
+ ls_subnet_del_all(args->ted, subnet);
+ }
te_debug(" |- Adjust prefix %pFX with local address to: %pFX",
prefix, &p);
+ }
/* Search existing Subnet in TED ... */
subnet = ls_find_subnet(args->ted, p);
if (!subnet) {
ls_pref = ls_prefix_new(vertex->node->adv, p);
subnet = ls_subnet_add(args->ted, ls_pref);
+ /* Stop processing if we are unable to create a new subnet */
if (!subnet)
return LSP_ITER_CONTINUE;
}
struct isis_lsp *lsp;
enum isis_tx_type type;
bool is_retry;
- struct thread *retry;
+ struct event *retry;
struct isis_tx_queue *queue;
};
{
struct isis_tx_queue_entry *e = element;
- THREAD_OFF(e->retry);
+ EVENT_OFF(e->retry);
XFREE(MTYPE_TX_QUEUE_ENTRY, e);
}
void isis_tx_queue_free(struct isis_tx_queue *queue)
{
- hash_clean(queue->hash, tx_queue_element_free);
- hash_free(queue->hash);
+ hash_clean_and_free(&queue->hash, tx_queue_element_free);
XFREE(MTYPE_TX_QUEUE, queue);
}
return hash_lookup(queue->hash, &e);
}
-static void tx_queue_send_event(struct thread *thread)
+static void tx_queue_send_event(struct event *thread)
{
- struct isis_tx_queue_entry *e = THREAD_ARG(thread);
+ struct isis_tx_queue_entry *e = EVENT_ARG(thread);
struct isis_tx_queue *queue = e->queue;
- thread_add_timer(master, tx_queue_send_event, e, 5, &e->retry);
+ event_add_timer(master, tx_queue_send_event, e, 5, &e->retry);
if (e->is_retry)
queue->circuit->area->lsp_rxmt_count++;
e->type = type;
- THREAD_OFF(e->retry);
- thread_add_event(master, tx_queue_send_event, e, 0, &e->retry);
+ EVENT_OFF(e->retry);
+ event_add_event(master, tx_queue_send_event, e, 0, &e->retry);
e->is_retry = false;
}
func, file, line);
}
- THREAD_OFF(e->retry);
+ EVENT_OFF(e->retry);
hash_release(queue->hash, e);
XFREE(MTYPE_TX_QUEUE_ENTRY, e);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "memory.h"
#include "log.h"
[ZEBRA_CLIENT_CLOSE_NOTIFY] = isis_zebra_client_close_notify,
};
-void isis_zebra_init(struct thread_master *master, int instance)
+void isis_zebra_init(struct event_loop *master, int instance)
{
/* Initialize asynchronous zclient. */
zclient = zclient_new(master, &zclient_options_default, isis_handlers,
};
#define CHUNK_SIZE 64
-void isis_zebra_init(struct thread_master *master, int instance);
+void isis_zebra_init(struct event_loop *master, int instance);
void isis_zebra_stop(void);
struct isis_route_info;
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "log.h"
struct isis_master *im;
/* ISIS config processing thread */
-struct thread *t_isis_cfg;
+struct event *t_isis_cfg;
#ifndef FABRICD
DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area));
return NULL;
}
-void isis_master_init(struct thread_master *master)
+void isis_master_init(struct event_loop *master)
{
memset(&isis_master, 0, sizeof(isis_master));
im = &isis_master;
area->area_addrs->del = delete_area_addr;
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
- thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
+ event_add_timer(master, lsp_tick, area, 1, &area->t_tick);
flags_initialize(&area->flags);
isis_sr_area_init(area);
spftree_area_del(area);
if (area->spf_timer[0])
- isis_spf_timer_free(THREAD_ARG(area->spf_timer[0]));
- THREAD_OFF(area->spf_timer[0]);
+ isis_spf_timer_free(EVENT_ARG(area->spf_timer[0]));
+ EVENT_OFF(area->spf_timer[0]);
if (area->spf_timer[1])
- isis_spf_timer_free(THREAD_ARG(area->spf_timer[1]));
- THREAD_OFF(area->spf_timer[1]);
+ isis_spf_timer_free(EVENT_ARG(area->spf_timer[1]));
+ EVENT_OFF(area->spf_timer[1]);
spf_backoff_free(area->spf_delay_ietf[0]);
spf_backoff_free(area->spf_delay_ietf[1]);
isis_lfa_tiebreakers_clear(area, ISIS_LEVEL1);
isis_lfa_tiebreakers_clear(area, ISIS_LEVEL2);
- THREAD_OFF(area->t_tick);
- THREAD_OFF(area->t_lsp_refresh[0]);
- THREAD_OFF(area->t_lsp_refresh[1]);
- THREAD_OFF(area->t_rlfa_rib_update);
+ EVENT_OFF(area->t_tick);
+ EVENT_OFF(area->t_lsp_refresh[0]);
+ EVENT_OFF(area->t_lsp_refresh[1]);
+ EVENT_OFF(area->t_rlfa_rib_update);
- thread_cancel_event(master, area);
+ event_cancel_event(master, area);
listnode_delete(area->isis->area_list, area);
vty_out(vty, " Level-%d:\n", level);
vty_out(vty, " SPF delay status: ");
if (area->spf_timer[level - 1]) {
- struct timeval remain = thread_timer_remain(
+ struct timeval remain = event_timer_remain(
area->spf_timer[level - 1]);
vty_out(vty, "Pending, due in %lld msec\n",
(long long)remain.tv_sec * 1000
vty_out(vty, " RX counters per PDU type:\n");
pdu_counter_print(vty, " ", area->pdu_rx_counters);
+ vty_out(vty, " Drop counters per PDU type:\n");
+ pdu_counter_print(vty, " ", area->pdu_drop_counters);
+
vty_out(vty, " Advertise high metrics: %s\n",
area->advertise_high_metrics ? "Enabled" : "Disabled");
}
if (area->spf_timer[level - 1])
- isis_spf_timer_free(THREAD_ARG(area->spf_timer[level - 1]));
+ isis_spf_timer_free(EVENT_ARG(area->spf_timer[level - 1]));
- THREAD_OFF(area->spf_timer[level - 1]);
+ EVENT_OFF(area->spf_timer[level - 1]);
sched_debug(
"ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
area->area_tag, level);
- THREAD_OFF(area->t_lsp_refresh[level - 1]);
+ EVENT_OFF(area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
}
} else {
/* Cancel overload on startup timer if it's running */
if (area->t_overload_on_startup_timer) {
- THREAD_OFF(area->t_overload_on_startup_timer);
+ EVENT_OFF(area->t_overload_on_startup_timer);
area->t_overload_on_startup_timer = NULL;
}
}
/* ISIS instance. */
struct list *isis;
/* ISIS thread master. */
- struct thread_master *master;
+ struct event_loop *master;
uint8_t options;
};
#define F_ISIS_UNIT_TEST 0x01
uint8_t max_area_addrs; /* maximumAreaAdresses */
struct area_addr *man_area_addrs; /* manualAreaAddresses */
time_t uptime; /* when did we start */
- struct thread *t_dync_clean; /* dynamic hostname cache cleanup thread */
+ struct event *t_dync_clean; /* dynamic hostname cache cleanup thread */
uint32_t circuit_ids_used[8]; /* 256 bits to track circuit ids 1 through 255 */
int snmp_notifications;
struct list *dyn_cache;
extern struct isis_master *im;
-extern struct thread *t_isis_cfg;
+extern struct event *t_isis_cfg;
enum spf_tree_id {
SPFTREE_IPV4 = 0,
struct list *circuit_list; /* IS-IS circuits */
struct list *adjacency_list; /* IS-IS adjacencies */
struct flags flags;
- struct thread *t_tick; /* LSP walker */
- struct thread *t_lsp_refresh[ISIS_LEVELS];
- struct thread *t_overload_on_startup_timer;
+ struct event *t_tick; /* LSP walker */
+ struct event *t_lsp_refresh[ISIS_LEVELS];
+ struct event *t_overload_on_startup_timer;
struct timeval last_lsp_refresh_event[ISIS_LEVELS];
- struct thread *t_rlfa_rib_update;
+ struct event *t_rlfa_rib_update;
/* t_lsp_refresh is used in two ways:
* a) regular refresh of LSPs
* b) (possibly throttled) updates to LSPs
struct spf_backoff *spf_delay_ietf[ISIS_LEVELS]; /*Structure with IETF
SPF algo
parameters*/
- struct thread *spf_timer[ISIS_LEVELS];
+ struct event *spf_timer[ISIS_LEVELS];
struct lsp_refresh_arg lsp_refresh_arg[ISIS_LEVELS];
pdu_counter_t pdu_tx_counters;
pdu_counter_t pdu_rx_counters;
+ pdu_counter_t pdu_drop_counters;
uint64_t lsp_rxmt_count;
/* Area counters */
DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area));
void isis_terminate(void);
-void isis_master_init(struct thread_master *master);
+void isis_master_init(struct event_loop *master);
void isis_vrf_link(struct isis *isis, struct vrf *vrf);
void isis_vrf_unlink(struct isis *isis, struct vrf *vrf);
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id);
#define ISIS_SR "/frr-isisd:isis/instance/segment-routing"
/* Master of threads. */
-extern struct thread_master *master;
+extern struct event_loop *master;
extern unsigned long debug_adj_pkt;
extern unsigned long debug_snp_pkt;
struct accept_ev {
LIST_ENTRY(accept_ev) entry;
- struct thread *ev;
- void (*accept_cb)(struct thread *);
+ struct event *ev;
+ void (*accept_cb)(struct event *);
void *arg;
int fd;
};
struct {
LIST_HEAD(, accept_ev) queue;
- struct thread *evt;
+ struct event *evt;
} accept_queue;
static void accept_arm(void);
static void accept_unarm(void);
-static void accept_cb(struct thread *);
-static void accept_timeout(struct thread *);
+static void accept_cb(struct event *);
+static void accept_timeout(struct event *);
void
accept_init(void)
LIST_INIT(&accept_queue.queue);
}
-int accept_add(int fd, void (*cb)(struct thread *), void *arg)
+int accept_add(int fd, void (*cb)(struct event *), void *arg)
{
struct accept_ev *av;
av->arg = arg;
LIST_INSERT_HEAD(&accept_queue.queue, av, entry);
- thread_add_read(master, accept_cb, av, av->fd, &av->ev);
+ event_add_read(master, accept_cb, av, av->fd, &av->ev);
log_debug("%s: accepting on fd %d", __func__, fd);
LIST_FOREACH(av, &accept_queue.queue, entry)
if (av->fd == fd) {
log_debug("%s: %d removed from queue", __func__, fd);
- THREAD_OFF(av->ev);
+ EVENT_OFF(av->ev);
LIST_REMOVE(av, entry);
free(av);
return;
{
log_debug(__func__);
accept_unarm();
- thread_add_timer(master, accept_timeout, NULL, 1, &accept_queue.evt);
+ event_add_timer(master, accept_timeout, NULL, 1, &accept_queue.evt);
}
void
{
if (accept_queue.evt != NULL) {
log_debug(__func__);
- THREAD_OFF(accept_queue.evt);
+ EVENT_OFF(accept_queue.evt);
accept_arm();
}
}
{
struct accept_ev *av;
LIST_FOREACH(av, &accept_queue.queue, entry) {
- thread_add_read(master, accept_cb, av, av->fd, &av->ev);
+ event_add_read(master, accept_cb, av, av->fd, &av->ev);
}
}
{
struct accept_ev *av;
LIST_FOREACH(av, &accept_queue.queue, entry)
- THREAD_OFF(av->ev);
+ EVENT_OFF(av->ev);
}
-static void accept_cb(struct thread *thread)
+static void accept_cb(struct event *thread)
{
- struct accept_ev *av = THREAD_ARG(thread);
- thread_add_read(master, accept_cb, av, av->fd, &av->ev);
+ struct accept_ev *av = EVENT_ARG(thread);
+ event_add_read(master, accept_cb, av, av->fd, &av->ev);
av->accept_cb(thread);
}
-static void accept_timeout(struct thread *thread)
+static void accept_timeout(struct event *thread)
{
accept_queue.evt = NULL;
#include "log.h"
static __inline int adj_compare(const struct adj *, const struct adj *);
-static void adj_itimer(struct thread *);
+static void adj_itimer(struct event *);
static __inline int tnbr_compare(const struct tnbr *, const struct tnbr *);
static void tnbr_del(struct ldpd_conf *, struct tnbr *);
static void tnbr_start(struct tnbr *);
static void tnbr_stop(struct tnbr *);
-static void tnbr_hello_timer(struct thread *);
+static void tnbr_hello_timer(struct event *);
static void tnbr_start_hello_timer(struct tnbr *);
static void tnbr_stop_hello_timer(struct tnbr *);
/* adjacency timers */
/* ARGSUSED */
-static void adj_itimer(struct thread *thread)
+static void adj_itimer(struct event *thread)
{
- struct adj *adj = THREAD_ARG(thread);
+ struct adj *adj = EVENT_ARG(thread);
adj->inactivity_timer = NULL;
void
adj_start_itimer(struct adj *adj)
{
- THREAD_OFF(adj->inactivity_timer);
+ EVENT_OFF(adj->inactivity_timer);
adj->inactivity_timer = NULL;
- thread_add_timer(master, adj_itimer, adj, adj->holdtime,
- &adj->inactivity_timer);
+ event_add_timer(master, adj_itimer, adj, adj->holdtime,
+ &adj->inactivity_timer);
}
void
adj_stop_itimer(struct adj *adj)
{
- THREAD_OFF(adj->inactivity_timer);
+ EVENT_OFF(adj->inactivity_timer);
}
/* targeted neighbors */
/* target neighbors timers */
/* ARGSUSED */
-static void tnbr_hello_timer(struct thread *thread)
+static void tnbr_hello_timer(struct event *thread)
{
- struct tnbr *tnbr = THREAD_ARG(thread);
+ struct tnbr *tnbr = EVENT_ARG(thread);
tnbr->hello_timer = NULL;
send_hello(HELLO_TARGETED, NULL, tnbr);
static void
tnbr_start_hello_timer(struct tnbr *tnbr)
{
- THREAD_OFF(tnbr->hello_timer);
+ EVENT_OFF(tnbr->hello_timer);
tnbr->hello_timer = NULL;
- thread_add_timer(master, tnbr_hello_timer, tnbr, tnbr_get_hello_interval(tnbr),
- &tnbr->hello_timer);
+ event_add_timer(master, tnbr_hello_timer, tnbr,
+ tnbr_get_hello_interval(tnbr), &tnbr->hello_timer);
}
static void
tnbr_stop_hello_timer(struct tnbr *tnbr)
{
- THREAD_OFF(tnbr->hello_timer);
+ EVENT_OFF(tnbr->hello_timer);
}
struct ctl_adj *
}
actl.holdtime = adj->holdtime;
actl.holdtime_remaining =
- thread_timer_remain_second(adj->inactivity_timer);
+ event_timer_remain_second(adj->inactivity_timer);
actl.trans_addr = adj->trans_addr;
actl.ds_tlv = adj->ds_tlv;
#define CONTROL_BACKLOG 5
-static void control_accept(struct thread *);
+static void control_accept(struct event *);
static struct ctl_conn *control_connbyfd(int);
static struct ctl_conn *control_connbypid(pid_t);
static void control_close(int);
-static void control_dispatch_imsg(struct thread *);
+static void control_dispatch_imsg(struct event *);
struct ctl_conns ctl_conns;
}
/* ARGSUSED */
-static void control_accept(struct thread *thread)
+static void control_accept(struct event *thread)
{
int connfd;
socklen_t len;
struct ctl_conn *c;
len = sizeof(s_un);
- if ((connfd = accept(THREAD_FD(thread), (struct sockaddr *)&s_un,
- &len)) == -1) {
+ if ((connfd = accept(EVENT_FD(thread), (struct sockaddr *)&s_un,
+ &len)) == -1) {
/*
* Pause accept if we are out of file descriptors, or
* libevent will haunt us here too.
imsg_init(&c->iev.ibuf, connfd);
c->iev.handler_read = control_dispatch_imsg;
c->iev.ev_read = NULL;
- thread_add_read(master, c->iev.handler_read, &c->iev, c->iev.ibuf.fd,
- &c->iev.ev_read);
+ event_add_read(master, c->iev.handler_read, &c->iev, c->iev.ibuf.fd,
+ &c->iev.ev_read);
c->iev.handler_write = ldp_write_handler;
c->iev.ev_write = NULL;
msgbuf_clear(&c->iev.ibuf.w);
TAILQ_REMOVE(&ctl_conns, c, entry);
- THREAD_OFF(c->iev.ev_read);
- THREAD_OFF(c->iev.ev_write);
+ EVENT_OFF(c->iev.ev_read);
+ EVENT_OFF(c->iev.ev_write);
close(c->iev.ibuf.fd);
accept_unpause();
free(c);
}
/* ARGSUSED */
-static void control_dispatch_imsg(struct thread *thread)
+static void control_dispatch_imsg(struct event *thread)
{
- int fd = THREAD_FD(thread);
+ int fd = EVENT_FD(thread);
struct ctl_conn *c;
struct imsg imsg;
ssize_t n;
static int if_start(struct iface *, int);
static int if_reset(struct iface *, int);
static void if_update_af(struct iface_af *);
-static void if_hello_timer(struct thread *thread);
+static void if_hello_timer(struct event *thread);
static void if_start_hello_timer(struct iface_af *);
static void if_stop_hello_timer(struct iface_af *);
static int if_join_ipv4_group(struct iface *, struct in_addr *);
static int ldp_sync_fsm_init(struct iface *iface, int state);
static int ldp_sync_act_iface_start_sync(struct iface *iface);
-static void iface_wait_for_ldp_sync_timer(struct thread *thread);
+static void iface_wait_for_ldp_sync_timer(struct event *thread);
static void start_wait_for_ldp_sync_timer(struct iface *iface);
static void stop_wait_for_ldp_sync_timer(struct iface *iface);
static int ldp_sync_act_ldp_start_sync(struct iface *iface);
/* timers */
/* ARGSUSED */
-static void if_hello_timer(struct thread *thread)
+static void if_hello_timer(struct event *thread)
{
- struct iface_af *ia = THREAD_ARG(thread);
+ struct iface_af *ia = EVENT_ARG(thread);
ia->hello_timer = NULL;
send_hello(HELLO_LINK, ia, NULL);
static void
if_start_hello_timer(struct iface_af *ia)
{
- THREAD_OFF(ia->hello_timer);
- thread_add_timer(master, if_hello_timer, ia, if_get_hello_interval(ia),
- &ia->hello_timer);
+ EVENT_OFF(ia->hello_timer);
+ event_add_timer(master, if_hello_timer, ia, if_get_hello_interval(ia),
+ &ia->hello_timer);
}
static void
if_stop_hello_timer(struct iface_af *ia)
{
- THREAD_OFF(ia->hello_timer);
+ EVENT_OFF(ia->hello_timer);
}
struct ctl_iface *
ictl.timer_running = iface->ldp_sync.wait_for_sync_timer ? true : false;
ictl.wait_time_remaining =
- thread_timer_remain_second(iface->ldp_sync.wait_for_sync_timer);
+ event_timer_remain_second(iface->ldp_sync.wait_for_sync_timer);
memset(&ictl.peer_ldp_id, 0, sizeof(ictl.peer_ldp_id));
return (0);
}
-static void iface_wait_for_ldp_sync_timer(struct thread *thread)
+static void iface_wait_for_ldp_sync_timer(struct event *thread)
{
- struct iface *iface = THREAD_ARG(thread);
+ struct iface *iface = EVENT_ARG(thread);
ldp_sync_fsm(iface, LDP_SYNC_EVT_LDP_SYNC_COMPLETE);
}
if (iface->ldp_sync.wait_for_sync_timer)
return;
- THREAD_OFF(iface->ldp_sync.wait_for_sync_timer);
- thread_add_timer(master, iface_wait_for_ldp_sync_timer, iface,
+ EVENT_OFF(iface->ldp_sync.wait_for_sync_timer);
+ event_add_timer(master, iface_wait_for_ldp_sync_timer, iface,
if_get_wait_for_sync_interval(),
&iface->ldp_sync.wait_for_sync_timer);
}
static void stop_wait_for_ldp_sync_timer(struct iface *iface)
{
- THREAD_OFF(iface->ldp_sync.wait_for_sync_timer);
+ EVENT_OFF(iface->ldp_sync.wait_for_sync_timer);
}
static int
#include "libfrr.h"
static void lde_shutdown(void);
-static void lde_dispatch_imsg(struct thread *thread);
-static void lde_dispatch_parent(struct thread *thread);
+static void lde_dispatch_imsg(struct event *thread);
+static void lde_dispatch_parent(struct event *thread);
static __inline int lde_nbr_compare(const struct lde_nbr *,
const struct lde_nbr *);
static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *);
fatal(NULL);
imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
iev_main->handler_read = lde_dispatch_parent;
- thread_add_read(master, iev_main->handler_read, iev_main, iev_main->ibuf.fd,
- &iev_main->ev_read);
+ event_add_read(master, iev_main->handler_read, iev_main,
+ iev_main->ibuf.fd, &iev_main->ev_read);
iev_main->handler_write = ldp_write_handler;
memset(&iev_main_sync_data, 0, sizeof(iev_main_sync_data));
/* create base configuration */
ldeconf = config_new_empty();
- struct thread thread;
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ struct event thread;
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* NOTREACHED */
return;
}
/* ARGSUSED */
-static void lde_dispatch_imsg(struct thread *thread)
+static void lde_dispatch_imsg(struct event *thread)
{
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
struct imsg imsg;
struct lde_nbr *ln;
imsg_event_add(iev);
else {
/* this pipe is dead, so remove the event handlers and exit */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
lde_shutdown();
}
}
/* ARGSUSED */
-static void lde_dispatch_parent(struct thread *thread)
+static void lde_dispatch_parent(struct event *thread)
{
static struct ldpd_conf *nconf;
struct iface *iface, *niface;
struct kif *kif;
struct kroute *kr;
int fd;
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
ssize_t n;
int shut = 0;
fatal(NULL);
imsg_init(&iev_ldpe->ibuf, fd);
iev_ldpe->handler_read = lde_dispatch_imsg;
- thread_add_read(master, iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd,
- &iev_ldpe->ev_read);
+ event_add_read(master, iev_ldpe->handler_read, iev_ldpe,
+ iev_ldpe->ibuf.fd, &iev_ldpe->ev_read);
iev_ldpe->handler_write = ldp_write_handler;
iev_ldpe->ev_write = NULL;
break;
imsg_event_add(iev);
else {
/* this pipe is dead, so remove the event handlers and exit */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
lde_shutdown();
}
}
/*
* Event callback used to retry the label-manager sync zapi session.
*/
-static void zclient_sync_retry(struct thread *thread)
+static void zclient_sync_retry(struct event *thread)
{
zclient_sync_init();
}
zclient_sync = NULL;
/* Retry using a timer */
- thread_add_timer(master, zclient_sync_retry, NULL, 1, NULL);
+ event_add_timer(master, zclient_sync_retry, NULL, 1, NULL);
}
static void
extern struct ldpd_conf *ldeconf;
extern struct fec_tree ft;
extern struct nbr_tree lde_nbrs;
-extern struct thread *gc_timer;
+extern struct event *gc_timer;
/* lde.c */
void lde(void);
void lde_check_withdraw_wcard(struct map *, struct lde_nbr *);
int lde_wildcard_apply(struct map *, struct fec *,
struct lde_map *);
-void lde_gc_timer(struct thread *thread);
+void lde_gc_timer(struct event *thread);
void lde_gc_start_timer(void);
void lde_gc_stop_timer(void);
RB_GENERATE(fec_tree, fec, entry, fec_compare)
struct fec_tree ft = RB_INITIALIZER(&ft);
-struct thread *gc_timer;
+struct event *gc_timer;
/* FEC tree functions */
void
/* gabage collector timer: timer to remove dead entries from the LIB */
/* ARGSUSED */
-void lde_gc_timer(struct thread *thread)
+void lde_gc_timer(struct event *thread)
{
struct fec *fec, *safe;
struct fec_node *fn;
void
lde_gc_start_timer(void)
{
- THREAD_OFF(gc_timer);
- thread_add_timer(master, lde_gc_timer, NULL, LDE_GC_INTERVAL,
- &gc_timer);
+ EVENT_OFF(gc_timer);
+ event_add_timer(master, lde_gc_timer, NULL, LDE_GC_INTERVAL, &gc_timer);
}
void
lde_gc_stop_timer(void)
{
- THREAD_OFF(gc_timer);
+ EVENT_OFF(gc_timer);
}
return 0;
}
-static int ldp_snmp_init(struct thread_master *tm)
+static int ldp_snmp_init(struct event_loop *tm)
{
hook_register(agentx_enabled, ldp_snmp_agentx_enabled);
return 0;
}
-static int ldp_snmp_register_mib(struct thread_master *tm)
+static int ldp_snmp_register_mib(struct event_loop *tm)
{
static int registered = 0;
zpw->nexthop.ipv6 = pw->addr.v6;
zpw->local_label = NO_LABEL;
zpw->remote_label = NO_LABEL;
- if (pw->flags & F_PW_CWORD)
+ if (CHECK_FLAG(pw->flags, F_PW_CWORD))
zpw->flags = F_PSEUDOWIRE_CWORD;
zpw->data.ldp.lsr_id = pw->lsr_id;
zpw->data.ldp.pwid = pw->pwid;
struct zapi_rlfa_igp igp;
struct zapi_rlfa_request rlfa;
- s = zclient->ibuf;
+ s = zclient->ibuf;
- if (zclient_opaque_decode(s, &info) != 0)
- return -1;
+ if(zclient_opaque_decode(s, &info) != 0)
+ return -1;
switch (info.type) {
case LDP_IGP_SYNC_IF_STATE_REQUEST:
* dropping them).
*/
if (kr->remote_label == NO_LABEL
- && !(ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
+ && !CHECK_FLAG(ldpd_conf->flags, F_LDPD_ALLOW_BROKEN_LSP)
&& cmd == ZEBRA_MPLS_LABELS_ADD)
return 0;
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
ifc2kaddr(ifp, ifc, &ka);
- main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
- sizeof(ka));
+ main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
}
}
}
if (if_is_operative(ifp)) {
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
ifc2kaddr(ifp, ifc, &ka);
- main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
- sizeof(ka));
+ main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
}
} else {
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
ifc2kaddr(ifp, ifc, &ka);
- main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka,
- sizeof(ka));
+ main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
}
}
switch (api.type) {
case ZEBRA_ROUTE_CONNECT:
- kr.flags |= F_CONNECTED;
+ SET_FLAG(kr.flags, F_CONNECTED);
break;
case ZEBRA_ROUTE_BGP:
/* LDP should follow the IGP and ignore BGP routes */
kr.ifindex = api_nh->ifindex;
break;
case NEXTHOP_TYPE_IFINDEX:
- if (!(kr.flags & F_CONNECTED))
+ if (!CHECK_FLAG(kr.flags, F_CONNECTED))
continue;
break;
case NEXTHOP_TYPE_BLACKHOLE:
zebra_route_string(api.type));
if (add)
- main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
- sizeof(kr));
+ main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr, sizeof(kr));
}
main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
/* if MPLS was already enabled and we are re-connecting, register again
*/
- if (vty_conf->flags & F_LDPD_ENABLED)
+ if (CHECK_FLAG(vty_conf->flags, F_LDPD_ENABLED))
ldp_zebra_regdereg_zebra_info(true);
ldp_zebra_opaque_register();
if (access && access->name[0] != '\0') {
strlcpy(laccess.name, access->name, sizeof(laccess.name));
- debug_evt("%s ACL update filter name %s", __func__,
- access->name);
+ debug_evt("%s ACL update filter name %s", __func__, access->name);
- main_imsg_compose_both(IMSG_FILTER_UPDATE, &laccess,
- sizeof(laccess));
+ main_imsg_compose_both(IMSG_FILTER_UPDATE, &laccess, sizeof(laccess));
}
}
[ZEBRA_OPAQUE_MESSAGE] = ldp_zebra_opaque_msg_handler,
};
-void
-ldp_zebra_init(struct thread_master *master)
+void ldp_zebra_init(struct event_loop *master)
{
- if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up,
- ldp_ifp_down, ldp_ifp_destroy);
+ if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up, ldp_ifp_down, ldp_ifp_destroy);
/* Set default values. */
zclient = zclient_new(master, &zclient_options_default, ldp_handlers,
static void ldpd_shutdown(void);
static pid_t start_child(enum ldpd_process, char *, int, int);
-static void main_dispatch_ldpe(struct thread *thread);
-static void main_dispatch_lde(struct thread *thread);
+static void main_dispatch_ldpe(struct event *thread);
+static void main_dispatch_lde(struct event *thread);
static int main_imsg_send_ipc_sockets(struct imsgbuf *,
struct imsgbuf *);
static void main_imsg_send_net_sockets(int);
static struct frr_daemon_info ldpd_di;
-DEFINE_HOOK(ldp_register_mib, (struct thread_master * tm), (tm));
+DEFINE_HOOK(ldp_register_mib, (struct event_loop * tm), (tm));
static void ldp_load_module(const char *name)
{
#define LDP_VTY_PORT 2612
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/* ldpd privileges */
static zebra_capabilities_t _caps_p [] =
.n_yang_modules = array_size(ldpd_yang_modules),
);
-static void ldp_config_fork_apply(struct thread *t)
+static void ldp_config_fork_apply(struct event *t)
{
/*
* So the frr_config_fork() function schedules
frr_config_fork();
/* apply configuration */
- thread_add_event(master, ldp_config_fork_apply, NULL, 0, NULL);
+ event_add_event(master, ldp_config_fork_apply, NULL, 0, NULL);
/* setup pipes to children */
if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
iev_ldpe->handler_read = main_dispatch_ldpe;
- thread_add_read(master, iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd,
- &iev_ldpe->ev_read);
+ event_add_read(master, iev_ldpe->handler_read, iev_ldpe,
+ iev_ldpe->ibuf.fd, &iev_ldpe->ev_read);
iev_ldpe->handler_write = ldp_write_handler;
imsg_init(&iev_ldpe_sync->ibuf, pipe_parent2ldpe_sync[0]);
iev_ldpe_sync->handler_read = main_dispatch_ldpe;
- thread_add_read(master, iev_ldpe_sync->handler_read, iev_ldpe_sync, iev_ldpe_sync->ibuf.fd,
- &iev_ldpe_sync->ev_read);
+ event_add_read(master, iev_ldpe_sync->handler_read, iev_ldpe_sync,
+ iev_ldpe_sync->ibuf.fd, &iev_ldpe_sync->ev_read);
iev_ldpe_sync->handler_write = ldp_write_handler;
imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
iev_lde->handler_read = main_dispatch_lde;
- thread_add_read(master, iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd,
- &iev_lde->ev_read);
+ event_add_read(master, iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd,
+ &iev_lde->ev_read);
iev_lde->handler_write = ldp_write_handler;
imsg_init(&iev_lde_sync->ibuf, pipe_parent2lde_sync[0]);
iev_lde_sync->handler_read = main_dispatch_lde;
- thread_add_read(master, iev_lde_sync->handler_read, iev_lde_sync, iev_lde_sync->ibuf.fd,
- &iev_lde_sync->ev_read);
+ event_add_read(master, iev_lde_sync->handler_read, iev_lde_sync,
+ iev_lde_sync->ibuf.fd, &iev_lde_sync->ev_read);
iev_lde_sync->handler_write = ldp_write_handler;
if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
/* imsg handling */
/* ARGSUSED */
-static void main_dispatch_ldpe(struct thread *thread)
+static void main_dispatch_ldpe(struct event *thread)
{
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
struct imsg imsg;
int af;
imsg_event_add(iev);
else {
/* this pipe is dead, so remove the event handlers and exit */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
ldpe_pid = 0;
if (lde_pid == 0)
}
/* ARGSUSED */
-static void main_dispatch_lde(struct thread *thread)
+static void main_dispatch_lde(struct event *thread)
{
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
struct imsg imsg;
ssize_t n;
imsg_event_add(iev);
else {
/* this pipe is dead, so remove the event handlers and exit */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
lde_pid = 0;
if (ldpe_pid == 0)
ldpd_shutdown();
}
/* ARGSUSED */
-void ldp_write_handler(struct thread *thread)
+void ldp_write_handler(struct event *thread)
{
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
ssize_t n;
fatal("msgbuf_write");
if (n == 0) {
/* this pipe is dead, so remove the event handlers */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
return;
}
imsg_event_add(struct imsgev *iev)
{
if (iev->handler_read)
- thread_add_read(master, iev->handler_read, iev, iev->ibuf.fd,
- &iev->ev_read);
+ event_add_read(master, iev->handler_read, iev, iev->ibuf.fd,
+ &iev->ev_read);
if (iev->handler_write && iev->ibuf.w.queued)
- thread_add_write(master, iev->handler_write, iev,
- iev->ibuf.fd, &iev->ev_write);
+ event_add_write(master, iev->handler_write, iev, iev->ibuf.fd,
+ &iev->ev_write);
}
int
evbuf_event_add(struct evbuf *eb)
{
if (eb->wbuf.queued)
- thread_add_write(master, eb->handler, eb->arg, eb->wbuf.fd,
- &eb->ev);
+ event_add_write(master, eb->handler, eb->arg, eb->wbuf.fd,
+ &eb->ev);
}
-void evbuf_init(struct evbuf *eb, int fd, void (*handler)(struct thread *),
+void evbuf_init(struct evbuf *eb, int fd, void (*handler)(struct event *),
void *arg)
{
msgbuf_init(&eb->wbuf);
void
evbuf_clear(struct evbuf *eb)
{
- THREAD_OFF(eb->ev);
+ EVENT_OFF(eb->ev);
msgbuf_clear(&eb->wbuf);
eb->wbuf.fd = -1;
}
#include "queue.h"
#include "openbsd-tree.h"
#include "imsg.h"
-#include "thread.h"
+#include "frrevent.h"
#include "qobj.h"
#include "prefix.h"
#include "filter.h"
struct evbuf {
struct msgbuf wbuf;
- struct thread *ev;
- void (*handler)(struct thread *);
+ struct event *ev;
+ void (*handler)(struct event *);
void *arg;
};
struct imsgev {
struct imsgbuf ibuf;
- void (*handler_write)(struct thread *);
- struct thread *ev_write;
- void (*handler_read)(struct thread *);
- struct thread *ev_read;
+ void (*handler_write)(struct event *);
+ struct event *ev_write;
+ void (*handler_read)(struct event *);
+ struct event *ev_read;
};
enum imsg_type {
int state;
struct ia_adj_head adj_tree;
time_t uptime;
- struct thread *hello_timer;
+ struct event *hello_timer;
uint16_t hello_holdtime;
uint16_t hello_interval;
};
struct iface_ldp_sync {
int state;
- struct thread *wait_for_sync_timer;
+ struct event *wait_for_sync_timer;
};
struct iface {
/* source of targeted hellos */
struct tnbr {
RB_ENTRY(tnbr) entry;
- struct thread *hello_timer;
+ struct event *hello_timer;
struct adj *adj;
int af;
union ldpd_addr addr;
#define F_LDPD_ALLOW_BROKEN_LSP 0x0010
struct ldpd_af_global {
- struct thread *disc_ev;
- struct thread *edisc_ev;
+ struct event *disc_ev;
+ struct event *edisc_ev;
int ldp_disc_socket;
int ldp_edisc_socket;
int ldp_session_socket;
socklen_t sockaddr_len(struct sockaddr *);
/* ldpd.c */
-void ldp_write_handler(struct thread *thread);
+void ldp_write_handler(struct event *thread);
void main_imsg_compose_ldpe(int, pid_t, void *, uint16_t);
void main_imsg_compose_lde(int, pid_t, void *, uint16_t);
int main_imsg_compose_both(enum imsg_type, void *,
pid_t, int, void *, uint16_t);
void evbuf_enqueue(struct evbuf *, struct ibuf *);
void evbuf_event_add(struct evbuf *);
-void evbuf_init(struct evbuf *, int, void (*)(struct thread *), void *);
+void evbuf_init(struct evbuf *, int, void (*)(struct event *), void *);
void evbuf_clear(struct evbuf *);
int ldp_acl_request(struct imsgev *, char *, int,
union ldpd_addr *, uint8_t);
const char *pw_error_code(uint8_t);
/* quagga */
-extern struct thread_master *master;
+extern struct event_loop *master;
extern char ctl_sock_path[MAXPATHLEN];
/* ldp_zebra.c */
-void ldp_zebra_init(struct thread_master *);
+void ldp_zebra_init(struct event_loop *m);
void ldp_zebra_destroy(void);
int ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *);
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));
+DECLARE_HOOK(ldp_register_mib, (struct event_loop * tm), (tm));
extern void ldp_agentx_enabled(void);
#include "libfrr.h"
static void ldpe_shutdown(void);
-static void ldpe_dispatch_main(struct thread *thread);
-static void ldpe_dispatch_lde(struct thread *thread);
+static void ldpe_dispatch_main(struct event *thread);
+static void ldpe_dispatch_lde(struct event *thread);
#ifdef __OpenBSD__
-static void ldpe_dispatch_pfkey(struct thread *thread);
+static void ldpe_dispatch_pfkey(struct event *thread);
#endif
static void ldpe_setup_sockets(int, int, int, int);
static void ldpe_close_sockets(int);
static struct imsgev *iev_main, *iev_main_sync;
static struct imsgev *iev_lde;
#ifdef __OpenBSD__
-static struct thread *pfkey_ev;
+static struct event *pfkey_ev;
#endif
/* ldpe privileges */
fatal(NULL);
imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
iev_main->handler_read = ldpe_dispatch_main;
- thread_add_read(master, iev_main->handler_read, iev_main, iev_main->ibuf.fd,
- &iev_main->ev_read);
+ event_add_read(master, iev_main->handler_read, iev_main,
+ iev_main->ibuf.fd, &iev_main->ev_read);
iev_main->handler_write = ldp_write_handler;
memset(&iev_main_data, 0, sizeof(iev_main_data));
/* create base configuration */
leconf = config_new_empty();
- struct thread thread;
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ struct event thread;
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* NOTREACHED */
return;
/* This socket must be open before dropping privileges. */
global.pfkeysock = pfkey_init();
if (sysdep.no_pfkey == 0) {
- thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
- &pfkey_ev);
+ event_add_read(master, ldpe_dispatch_pfkey, NULL,
+ global.pfkeysock, &pfkey_ev);
}
#endif
#ifdef __OpenBSD__
if (sysdep.no_pfkey == 0) {
- THREAD_OFF(pfkey_ev);
+ EVENT_OFF(pfkey_ev);
close(global.pfkeysock);
}
#endif
}
/* ARGSUSED */
-static void ldpe_dispatch_main(struct thread *thread)
+static void ldpe_dispatch_main(struct event *thread)
{
static struct ldpd_conf *nconf;
struct iface *niface;
struct l2vpn_pw *pw, *npw;
struct imsg imsg;
int fd;
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
struct iface *iface = NULL;
struct kif *kif;
fatal(NULL);
imsg_init(&iev_lde->ibuf, fd);
iev_lde->handler_read = ldpe_dispatch_lde;
- thread_add_read(master, iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd,
- &iev_lde->ev_read);
+ event_add_read(master, iev_lde->handler_read, iev_lde,
+ iev_lde->ibuf.fd, &iev_lde->ev_read);
iev_lde->handler_write = ldp_write_handler;
iev_lde->ev_write = NULL;
break;
imsg_event_add(iev);
else {
/* this pipe is dead, so remove the event handlers and exit */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
ldpe_shutdown();
}
}
/* ARGSUSED */
-static void ldpe_dispatch_lde(struct thread *thread)
+static void ldpe_dispatch_lde(struct event *thread)
{
- struct imsgev *iev = THREAD_ARG(thread);
+ struct imsgev *iev = EVENT_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
struct imsg imsg;
struct map *map;
imsg_event_add(iev);
else {
/* this pipe is dead, so remove the event handlers and exit */
- THREAD_OFF(iev->ev_read);
- THREAD_OFF(iev->ev_write);
+ EVENT_OFF(iev->ev_read);
+ EVENT_OFF(iev->ev_write);
ldpe_shutdown();
}
}
#ifdef __OpenBSD__
/* ARGSUSED */
-static void ldpe_dispatch_pfkey(struct thread *thread)
+static void ldpe_dispatch_pfkey(struct event *thread)
{
- int fd = THREAD_FD(thread);
+ int fd = EVENT_FD(thread);
- thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
- &pfkey_ev);
+ event_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
+ &pfkey_ev);
if (pfkey_read(fd, NULL) == -1)
fatal("pfkey_read failed, exiting...");
/* discovery socket */
af_global->ldp_disc_socket = disc_socket;
- thread_add_read(master, disc_recv_packet, &af_global->disc_ev, af_global->ldp_disc_socket,
- &af_global->disc_ev);
+ event_add_read(master, disc_recv_packet, &af_global->disc_ev,
+ af_global->ldp_disc_socket, &af_global->disc_ev);
/* extended discovery socket */
af_global->ldp_edisc_socket = edisc_socket;
- thread_add_read(master, disc_recv_packet, &af_global->edisc_ev, af_global->ldp_edisc_socket,
- &af_global->edisc_ev);
+ event_add_read(master, disc_recv_packet, &af_global->edisc_ev,
+ af_global->ldp_edisc_socket, &af_global->edisc_ev);
/* session socket */
af_global->ldp_session_socket = session_socket;
af_global = ldp_af_global_get(&global, af);
/* discovery socket */
- THREAD_OFF(af_global->disc_ev);
+ EVENT_OFF(af_global->disc_ev);
if (af_global->ldp_disc_socket != -1) {
close(af_global->ldp_disc_socket);
af_global->ldp_disc_socket = -1;
}
/* extended discovery socket */
- THREAD_OFF(af_global->edisc_ev);
+ EVENT_OFF(af_global->edisc_ev);
if (af_global->ldp_edisc_socket != -1) {
close(af_global->ldp_edisc_socket);
af_global->ldp_edisc_socket = -1;
struct nbr *nbr;
int ds_tlv;
struct hello_source source;
- struct thread *inactivity_timer;
+ struct event *inactivity_timer;
uint16_t holdtime;
union ldpd_addr trans_addr;
};
int fd;
struct ibuf_read *rbuf;
struct evbuf wbuf;
- struct thread *rev;
+ struct event *rev;
in_port_t lport;
in_port_t rport;
};
RB_ENTRY(nbr) id_tree, addr_tree, pid_tree;
struct tcp_conn *tcp;
struct nbr_adj_head adj_tree; /* adjacencies */
- struct thread *ev_connect;
- struct thread *keepalive_timer;
- struct thread *keepalive_timeout;
- struct thread *init_timeout;
- struct thread *initdelay_timer;
+ struct event *ev_connect;
+ struct event *keepalive_timer;
+ struct event *keepalive_timeout;
+ struct event *init_timeout;
+ struct event *initdelay_timer;
struct mapping_head mapping_list;
struct mapping_head withdraw_list;
int fd;
int af;
union ldpd_addr addr;
- struct thread *ev_timeout;
+ struct event *ev_timeout;
};
#define PENDING_CONN_TIMEOUT 5
/* accept.c */
void accept_init(void);
-int accept_add(int, void (*)(struct thread *), void *);
+int accept_add(int, void (*)(struct event *), void *);
void accept_del(int);
void accept_pause(void);
void accept_unpause(void);
int gen_msg_hdr(struct ibuf *, uint16_t, uint16_t);
int send_packet(int, int, union ldpd_addr *,
struct iface_af *, void *, size_t);
-void disc_recv_packet(struct thread *thread);
-void session_accept(struct thread *thread);
+void disc_recv_packet(struct event *thread);
+void session_accept(struct event *thread);
void session_accept_nbr(struct nbr *, int);
void session_shutdown(struct nbr *, uint32_t, uint32_t,
uint32_t);
static __inline int nbr_pid_compare(const struct nbr *,
const struct nbr *);
static void nbr_update_peerid(struct nbr *);
-static void nbr_ktimer(struct thread *thread);
+static void nbr_ktimer(struct event *thread);
static void nbr_start_ktimer(struct nbr *);
-static void nbr_ktimeout(struct thread *thread);
+static void nbr_ktimeout(struct event *thread);
static void nbr_start_ktimeout(struct nbr *);
-static void nbr_itimeout(struct thread *thread);
+static void nbr_itimeout(struct event *thread);
static void nbr_start_itimeout(struct nbr *);
-static void nbr_idtimer(struct thread *thread);
+static void nbr_idtimer(struct event *thread);
static int nbr_act_session_operational(struct nbr *);
static void nbr_send_labelmappings(struct nbr *);
static __inline int nbr_params_compare(const struct nbr_params *,
nbr->auth.method = AUTH_NONE;
if (nbr_pending_connect(nbr))
- THREAD_OFF(nbr->ev_connect);
+ EVENT_OFF(nbr->ev_connect);
nbr_stop_ktimer(nbr);
nbr_stop_ktimeout(nbr);
nbr_stop_itimeout(nbr);
/* Keepalive timer: timer to send keepalive message to neighbors */
-static void nbr_ktimer(struct thread *thread)
+static void nbr_ktimer(struct event *thread)
{
- struct nbr *nbr = THREAD_ARG(thread);
+ struct nbr *nbr = EVENT_ARG(thread);
nbr->keepalive_timer = NULL;
send_keepalive(nbr);
/* send three keepalives per period */
secs = nbr->keepalive / KEEPALIVE_PER_PERIOD;
- THREAD_OFF(nbr->keepalive_timer);
+ EVENT_OFF(nbr->keepalive_timer);
nbr->keepalive_timer = NULL;
- thread_add_timer(master, nbr_ktimer, nbr, secs, &nbr->keepalive_timer);
+ event_add_timer(master, nbr_ktimer, nbr, secs, &nbr->keepalive_timer);
}
void
nbr_stop_ktimer(struct nbr *nbr)
{
- THREAD_OFF(nbr->keepalive_timer);
+ EVENT_OFF(nbr->keepalive_timer);
}
/* Keepalive timeout: if the nbr hasn't sent keepalive */
-static void nbr_ktimeout(struct thread *thread)
+static void nbr_ktimeout(struct event *thread)
{
- struct nbr *nbr = THREAD_ARG(thread);
+ struct nbr *nbr = EVENT_ARG(thread);
nbr->keepalive_timeout = NULL;
static void
nbr_start_ktimeout(struct nbr *nbr)
{
- THREAD_OFF(nbr->keepalive_timeout);
+ EVENT_OFF(nbr->keepalive_timeout);
nbr->keepalive_timeout = NULL;
- thread_add_timer(master, nbr_ktimeout, nbr, nbr->keepalive,
- &nbr->keepalive_timeout);
+ event_add_timer(master, nbr_ktimeout, nbr, nbr->keepalive,
+ &nbr->keepalive_timeout);
}
void
nbr_stop_ktimeout(struct nbr *nbr)
{
- THREAD_OFF(nbr->keepalive_timeout);
+ EVENT_OFF(nbr->keepalive_timeout);
}
/* Session initialization timeout: if nbr got stuck in the initialization FSM */
-static void nbr_itimeout(struct thread *thread)
+static void nbr_itimeout(struct event *thread)
{
- struct nbr *nbr = THREAD_ARG(thread);
+ struct nbr *nbr = EVENT_ARG(thread);
log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
int secs;
secs = INIT_FSM_TIMEOUT;
- THREAD_OFF(nbr->init_timeout);
+ EVENT_OFF(nbr->init_timeout);
nbr->init_timeout = NULL;
- thread_add_timer(master, nbr_itimeout, nbr, secs, &nbr->init_timeout);
+ event_add_timer(master, nbr_itimeout, nbr, secs, &nbr->init_timeout);
}
void
nbr_stop_itimeout(struct nbr *nbr)
{
- THREAD_OFF(nbr->init_timeout);
+ EVENT_OFF(nbr->init_timeout);
}
/* Init delay timer: timer to retry to iniziatize session */
-static void nbr_idtimer(struct thread *thread)
+static void nbr_idtimer(struct event *thread)
{
- struct nbr *nbr = THREAD_ARG(thread);
+ struct nbr *nbr = EVENT_ARG(thread);
nbr->initdelay_timer = NULL;
break;
}
- THREAD_OFF(nbr->initdelay_timer);
+ EVENT_OFF(nbr->initdelay_timer);
nbr->initdelay_timer = NULL;
- thread_add_timer(master, nbr_idtimer, nbr, secs,
- &nbr->initdelay_timer);
+ event_add_timer(master, nbr_idtimer, nbr, secs, &nbr->initdelay_timer);
}
void
nbr_stop_idtimer(struct nbr *nbr)
{
- THREAD_OFF(nbr->initdelay_timer);
+ EVENT_OFF(nbr->initdelay_timer);
}
int
return (nbr->ev_connect != NULL);
}
-static void nbr_connect_cb(struct thread *thread)
+static void nbr_connect_cb(struct event *thread)
{
- struct nbr *nbr = THREAD_ARG(thread);
+ struct nbr *nbr = EVENT_ARG(thread);
int error;
socklen_t len;
if (connect(nbr->fd, &remote_su.sa, sockaddr_len(&remote_su.sa))
== -1) {
if (errno == EINPROGRESS) {
- thread_add_write(master, nbr_connect_cb, nbr, nbr->fd,
- &nbr->ev_connect);
+ event_add_write(master, nbr_connect_cb, nbr, nbr->fd,
+ &nbr->ev_connect);
return (0);
}
log_warn("%s: error while connecting to %s", __func__,
nctl.flags = nbr->flags;
nctl.max_pdu_len = nbr->max_pdu_len;
nctl.hold_time_remaining =
- thread_timer_remain_second(nbr->keepalive_timer);
+ event_timer_remain_second(nbr->keepalive_timer);
gettimeofday(&now, NULL);
if (nbr->state == NBR_STA_OPER) {
static struct iface *disc_find_iface(unsigned int, int,
union ldpd_addr *);
-static void session_read(struct thread *thread);
-static void session_write(struct thread *thread);
+static void session_read(struct event *thread);
+static void session_write(struct event *thread);
static ssize_t session_get_pdu(struct ibuf_read *, char **);
static void tcp_close(struct tcp_conn *);
static struct pending_conn *pending_conn_new(int, int, union ldpd_addr *);
-static void pending_conn_timeout(struct thread *thread);
+static void pending_conn_timeout(struct event *thread);
int
gen_ldp_hdr(struct ibuf *buf, uint16_t size)
}
/* Discovery functions */
-void disc_recv_packet(struct thread *thread)
+void disc_recv_packet(struct event *thread)
{
- int fd = THREAD_FD(thread);
- struct thread **threadp = THREAD_ARG(thread);
+ int fd = EVENT_FD(thread);
+ struct event **threadp = EVENT_ARG(thread);
union {
struct cmsghdr hdr;
struct in_addr lsr_id;
/* reschedule read */
- thread_add_read(master, disc_recv_packet, threadp, fd, threadp);
+ event_add_read(master, disc_recv_packet, threadp, fd, threadp);
/* setup buffer */
memset(&m, 0, sizeof(m));
return (iface);
}
-void session_accept(struct thread *thread)
+void session_accept(struct event *thread)
{
- int fd = THREAD_FD(thread);
+ int fd = EVENT_FD(thread);
struct sockaddr_storage src;
socklen_t len = sizeof(src);
int newfd;
nbr_fsm(nbr, NBR_EVT_MATCH_ADJ);
}
-static void session_read(struct thread *thread)
+static void session_read(struct event *thread)
{
- int fd = THREAD_FD(thread);
- struct nbr *nbr = THREAD_ARG(thread);
+ int fd = EVENT_FD(thread);
+ struct nbr *nbr = EVENT_ARG(thread);
struct tcp_conn *tcp = nbr->tcp;
struct ldp_hdr *ldp_hdr;
struct ldp_msg *msg;
uint16_t pdu_len, msg_len, msg_size, max_pdu_len;
int ret;
- thread_add_read(master, session_read, nbr, fd, &tcp->rev);
+ event_add_read(master, session_read, nbr, fd, &tcp->rev);
if ((n = read(fd, tcp->rbuf->buf + tcp->rbuf->wpos,
sizeof(tcp->rbuf->buf) - tcp->rbuf->wpos)) == -1) {
free(buf);
}
-static void session_write(struct thread *thread)
+static void session_write(struct event *thread)
{
- struct tcp_conn *tcp = THREAD_ARG(thread);
+ struct tcp_conn *tcp = EVENT_ARG(thread);
struct nbr *nbr = tcp->nbr;
tcp->wbuf.ev = NULL;
switch (nbr->state) {
case NBR_STA_PRESENT:
if (nbr_pending_connect(nbr))
- THREAD_OFF(nbr->ev_connect);
+ EVENT_OFF(nbr->ev_connect);
break;
case NBR_STA_INITIAL:
case NBR_STA_OPENREC:
if ((tcp->rbuf = calloc(1, sizeof(struct ibuf_read))) == NULL)
fatal(__func__);
- thread_add_read(master, session_read, nbr, tcp->fd, &tcp->rev);
+ event_add_read(master, session_read, nbr, tcp->fd, &tcp->rev);
tcp->nbr = nbr;
}
evbuf_clear(&tcp->wbuf);
if (tcp->nbr) {
- THREAD_OFF(tcp->rev);
+ EVENT_OFF(tcp->rev);
free(tcp->rbuf);
tcp->nbr->tcp = NULL;
}
pconn->addr = *addr;
TAILQ_INSERT_TAIL(&global.pending_conns, pconn, entry);
pconn->ev_timeout = NULL;
- thread_add_timer(master, pending_conn_timeout, pconn, PENDING_CONN_TIMEOUT,
- &pconn->ev_timeout);
+ event_add_timer(master, pending_conn_timeout, pconn,
+ PENDING_CONN_TIMEOUT, &pconn->ev_timeout);
return (pconn);
}
void
pending_conn_del(struct pending_conn *pconn)
{
- THREAD_OFF(pconn->ev_timeout);
+ EVENT_OFF(pconn->ev_timeout);
TAILQ_REMOVE(&global.pending_conns, pconn, entry);
free(pconn);
}
return (NULL);
}
-static void pending_conn_timeout(struct thread *thread)
+static void pending_conn_timeout(struct event *thread)
{
- struct pending_conn *pconn = THREAD_ARG(thread);
+ struct pending_conn *pconn = EVENT_ARG(thread);
struct tcp_conn *tcp;
pconn->ev_timeout = NULL;
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;
return agentx_enabled;
}
-void smux_init(struct thread_master *tm)
+void smux_init(struct event_loop *tm)
{
agentx_tm = tm;
#include "command.h"
#include "memory.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#include "vrf.h"
#include "zclient.h"
* Next event.
*
* This variable controls what action to execute when the command batch
- * finishes. Normally we'd use `thread_add_event` value, however since
+ * finishes. Normally we'd use `event_add_event` value, however since
* that function is going to be called multiple times and the value
* might be different we'll use this variable to keep track of it.
*/
* configuration load or northbound batch), so we'll use this to
* install/uninstall the BFD session parameters only once.
*/
- struct thread *installev;
+ struct event *installev;
/** BFD session installation state. */
bool installed;
struct bfd_source_list source_list;
/** Pointer to FRR's event manager. */
- struct thread_master *tm;
+ struct event_loop *tm;
/** Pointer to zebra client data structure. */
struct zclient *zc;
return true;
}
-static void _bfd_sess_send(struct thread *t)
+static void _bfd_sess_send(struct event *t)
{
- struct bfd_session_params *bsp = THREAD_ARG(t);
+ struct bfd_session_params *bsp = EVENT_ARG(t);
int rv;
/* Validate configuration before trying to send bogus data. */
static void _bfd_sess_remove(struct bfd_session_params *bsp)
{
/* Cancel any pending installation request. */
- THREAD_OFF(bsp->installev);
+ EVENT_OFF(bsp->installev);
/* Not installed, nothing to do. */
if (!bsp->installed)
/* Send request to remove any session. */
bsp->lastev = BSE_UNINSTALL;
- thread_execute(bsglobal.tm, _bfd_sess_send, bsp, 0);
+ event_execute(bsglobal.tm, _bfd_sess_send, bsp, 0);
}
void bfd_sess_free(struct bfd_session_params **bsp)
void bfd_sess_install(struct bfd_session_params *bsp)
{
bsp->lastev = BSE_INSTALL;
- thread_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev);
+ event_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev);
}
void bfd_sess_uninstall(struct bfd_session_params *bsp)
{
bsp->lastev = BSE_UNINSTALL;
- thread_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev);
+ event_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev);
}
enum bfd_session_state bfd_sess_status(const struct bfd_session_params *bsp)
bsp->installed = false;
/* Cancel any pending installation request. */
- THREAD_OFF(bsp->installev);
+ EVENT_OFF(bsp->installev);
/* Ask for installation. */
bsp->lastev = BSE_INSTALL;
- thread_execute(bsglobal.tm, _bfd_sess_send, bsp, 0);
+ event_execute(bsglobal.tm, _bfd_sess_send, bsp, 0);
}
return 0;
return 0;
}
-void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm)
+void bfd_protocol_integration_init(struct zclient *zc, struct event_loop *tm)
{
/* Initialize data structure. */
TAILQ_INIT(&bsglobal.bsplist);
* Initializes the BFD integration library. This function executes the
* following actions:
*
- * - Copy the `struct thread_master` pointer to use as "thread" to execute
+ * - Copy the `struct event_loop` pointer to use as "thread" to execute
* the BFD session parameters installation.
* - Copy the `struct zclient` pointer to install its callbacks.
* - Initializes internal data structures.
* \param tm normally the daemon main thread event manager.
* \param zc the zebra client of the daemon.
*/
-void bfd_protocol_integration_init(struct zclient *zc,
- struct thread_master *tm);
+void bfd_protocol_integration_init(struct zclient *zc, struct event_loop *tm);
/**
* BFD session registration arguments.
#include "memory.h"
#include "log.h"
#include "log_vty.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vector.h"
#include "linklist.h"
#include "vty.h"
install_default(CONFIG_NODE);
- thread_cmd_init();
+ event_cmd_init();
workqueue_cmd_init();
hash_cmd_init();
}
// well
graph_delete_graph(cmd_node->cmdgraph);
vector_free(cmd_node->cmd_vector);
- hash_clean(cmd_node->cmd_hash, NULL);
- hash_free(cmd_node->cmd_hash);
- cmd_node->cmd_hash = NULL;
+ hash_clean_and_free(&cmd_node->cmd_hash, NULL);
}
vector_free(cmdvec);
char string_end;
char *value;
+static const char *yyfilename;
static void extendbuf(char **what, const char *arg)
{
}
}
<rstring>\\\n /* ignore */
+<rstring>\n {
+ fprintf(stderr,
+ "%s:%d: string continues past the end of the line\n",
+ yyfilename, yylineno);
+ free(value);
+ value = NULL;
+ BEGIN(INITIAL);
+ return STRING;
+ }
<rstring>\\. extend(yytext);
-<rstring>[^\\\"\']+ extend(yytext);
+<rstring>[^\\\"\'\n]+ extend(yytext);
"DEFUN" value = strdup(yytext); return DEFUNNY;
"DEFUN_NOSH" value = strdup(yytext); return DEFUNNY;
if (tval[0] == ')')
depth--;
}
+ if (!tval)
+ return PyErr_Format(PyExc_ValueError,
+ "%s:%d: invalid token in DEFPY parameters",
+ filename, lineno);
if (!pyArg)
pyArg = PyList_New(0);
PyList_Append(pyArg, PyUnicode_FromString(tval));
int token;
yyin = fd;
value = NULL;
+ yyfilename = filename;
PyObject *pyCont = PyDict_New();
PyObject *pyObj = PyList_New(0);
if (!pyArgs) {
free(tval);
Py_DECREF(pyCont);
+ yyfilename = NULL;
return NULL;
}
pyItem = PyDict_New();
}
def_yylex_destroy();
fclose(fd);
+ yyfilename = NULL;
return pyCont;
}
void distribute_list_delete(struct distribute_ctx **ctx)
{
- if ((*ctx)->disthash) {
- hash_clean((*ctx)->disthash, (void (*)(void *))distribute_free);
+ hash_clean_and_free(&(*ctx)->disthash,
+ (void (*)(void *))distribute_free);
+
+ if (dist_ctx_list) {
+ listnode_delete(dist_ctx_list, *ctx);
+ if (list_isempty(dist_ctx_list))
+ list_delete(&dist_ctx_list);
}
- if (!dist_ctx_list)
- dist_ctx_list = list_new();
- listnode_delete(dist_ctx_list, *ctx);
- if (list_isempty(dist_ctx_list))
- list_delete(&dist_ctx_list);
+
XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx));
}
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Thread management routine
+ * Copyright (C) 1998, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ */
+
+/* #define DEBUG */
+
+#include <zebra.h>
+#include <sys/resource.h>
+
+#include "frrevent.h"
+#include "memory.h"
+#include "frrcu.h"
+#include "log.h"
+#include "hash.h"
+#include "command.h"
+#include "sigevent.h"
+#include "network.h"
+#include "jhash.h"
+#include "frratomic.h"
+#include "frr_pthread.h"
+#include "lib_errors.h"
+#include "libfrr_trace.h"
+#include "libfrr.h"
+
+DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread");
+DEFINE_MTYPE_STATIC(LIB, EVENT_MASTER, "Thread master");
+DEFINE_MTYPE_STATIC(LIB, EVENT_POLL, "Thread Poll Info");
+DEFINE_MTYPE_STATIC(LIB, EVENT_STATS, "Thread stats");
+
+DECLARE_LIST(event_list, struct event, eventitem);
+
+struct cancel_req {
+ int flags;
+ struct event *thread;
+ void *eventobj;
+ struct event **threadref;
+};
+
+/* Flags for task cancellation */
+#define EVENT_CANCEL_FLAG_READY 0x01
+
+static int event_timer_cmp(const struct event *a, const struct event *b)
+{
+ if (a->u.sands.tv_sec < b->u.sands.tv_sec)
+ return -1;
+ if (a->u.sands.tv_sec > b->u.sands.tv_sec)
+ return 1;
+ if (a->u.sands.tv_usec < b->u.sands.tv_usec)
+ return -1;
+ if (a->u.sands.tv_usec > b->u.sands.tv_usec)
+ return 1;
+ return 0;
+}
+
+DECLARE_HEAP(event_timer_list, struct event, timeritem, event_timer_cmp);
+
+#if defined(__APPLE__)
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#endif
+
+#define AWAKEN(m) \
+ do { \
+ const unsigned char wakebyte = 0x01; \
+ write(m->io_pipe[1], &wakebyte, 1); \
+ } while (0)
+
+/* control variable for initializer */
+static pthread_once_t init_once = PTHREAD_ONCE_INIT;
+pthread_key_t thread_current;
+
+static pthread_mutex_t masters_mtx = PTHREAD_MUTEX_INITIALIZER;
+static struct list *masters;
+
+static void thread_free(struct event_loop *master, struct event *thread);
+
+#ifndef EXCLUDE_CPU_TIME
+#define EXCLUDE_CPU_TIME 0
+#endif
+#ifndef CONSUMED_TIME_CHECK
+#define CONSUMED_TIME_CHECK 0
+#endif
+
+bool cputime_enabled = !EXCLUDE_CPU_TIME;
+unsigned long cputime_threshold = CONSUMED_TIME_CHECK;
+unsigned long walltime_threshold = CONSUMED_TIME_CHECK;
+
+/* CLI start ---------------------------------------------------------------- */
+#include "lib/event_clippy.c"
+
+static unsigned int cpu_record_hash_key(const struct cpu_event_history *a)
+{
+ int size = sizeof(a->func);
+
+ return jhash(&a->func, size, 0);
+}
+
+static bool cpu_record_hash_cmp(const struct cpu_event_history *a,
+ const struct cpu_event_history *b)
+{
+ return a->func == b->func;
+}
+
+static void *cpu_record_hash_alloc(struct cpu_event_history *a)
+{
+ struct cpu_event_history *new;
+
+ new = XCALLOC(MTYPE_EVENT_STATS, sizeof(struct cpu_event_history));
+ new->func = a->func;
+ new->funcname = a->funcname;
+ return new;
+}
+
+static void cpu_record_hash_free(void *a)
+{
+ struct cpu_event_history *hist = a;
+
+ XFREE(MTYPE_EVENT_STATS, hist);
+}
+
+static void vty_out_cpu_event_history(struct vty *vty,
+ struct cpu_event_history *a)
+{
+ vty_out(vty,
+ "%5zu %10zu.%03zu %9zu %8zu %9zu %8zu %9zu %9zu %9zu %10zu",
+ a->total_active, a->cpu.total / 1000, a->cpu.total % 1000,
+ a->total_calls, (a->cpu.total / a->total_calls), a->cpu.max,
+ (a->real.total / a->total_calls), a->real.max,
+ a->total_cpu_warn, a->total_wall_warn, a->total_starv_warn);
+ vty_out(vty, " %c%c%c%c%c %s\n",
+ a->types & (1 << EVENT_READ) ? 'R' : ' ',
+ a->types & (1 << EVENT_WRITE) ? 'W' : ' ',
+ a->types & (1 << EVENT_TIMER) ? 'T' : ' ',
+ a->types & (1 << EVENT_EVENT) ? 'E' : ' ',
+ a->types & (1 << EVENT_EXECUTE) ? 'X' : ' ', a->funcname);
+}
+
+static void cpu_record_hash_print(struct hash_bucket *bucket, void *args[])
+{
+ struct cpu_event_history *totals = args[0];
+ struct cpu_event_history copy;
+ struct vty *vty = args[1];
+ uint8_t *filter = args[2];
+
+ struct cpu_event_history *a = bucket->data;
+
+ copy.total_active =
+ atomic_load_explicit(&a->total_active, memory_order_seq_cst);
+ copy.total_calls =
+ atomic_load_explicit(&a->total_calls, memory_order_seq_cst);
+ copy.total_cpu_warn =
+ atomic_load_explicit(&a->total_cpu_warn, memory_order_seq_cst);
+ copy.total_wall_warn =
+ atomic_load_explicit(&a->total_wall_warn, memory_order_seq_cst);
+ copy.total_starv_warn = atomic_load_explicit(&a->total_starv_warn,
+ memory_order_seq_cst);
+ copy.cpu.total =
+ atomic_load_explicit(&a->cpu.total, memory_order_seq_cst);
+ copy.cpu.max = atomic_load_explicit(&a->cpu.max, memory_order_seq_cst);
+ copy.real.total =
+ atomic_load_explicit(&a->real.total, memory_order_seq_cst);
+ copy.real.max =
+ atomic_load_explicit(&a->real.max, memory_order_seq_cst);
+ copy.types = atomic_load_explicit(&a->types, memory_order_seq_cst);
+ copy.funcname = a->funcname;
+
+ if (!(copy.types & *filter))
+ return;
+
+ vty_out_cpu_event_history(vty, ©);
+ totals->total_active += copy.total_active;
+ totals->total_calls += copy.total_calls;
+ totals->total_cpu_warn += copy.total_cpu_warn;
+ totals->total_wall_warn += copy.total_wall_warn;
+ totals->total_starv_warn += copy.total_starv_warn;
+ totals->real.total += copy.real.total;
+ if (totals->real.max < copy.real.max)
+ totals->real.max = copy.real.max;
+ totals->cpu.total += copy.cpu.total;
+ if (totals->cpu.max < copy.cpu.max)
+ totals->cpu.max = copy.cpu.max;
+}
+
+static void cpu_record_print(struct vty *vty, uint8_t filter)
+{
+ struct cpu_event_history tmp;
+ void *args[3] = {&tmp, vty, &filter};
+ struct event_loop *m;
+ struct listnode *ln;
+
+ if (!cputime_enabled)
+ vty_out(vty,
+ "\n"
+ "Collecting CPU time statistics is currently disabled. Following statistics\n"
+ "will be zero or may display data from when collection was enabled. Use the\n"
+ " \"service cputime-stats\" command to start collecting data.\n"
+ "\nCounters and wallclock times are always maintained and should be accurate.\n");
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.funcname = "TOTAL";
+ tmp.types = filter;
+
+ frr_with_mutex (&masters_mtx) {
+ for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) {
+ const char *name = m->name ? m->name : "main";
+ char underline[strlen(name) + 1];
+
+ memset(underline, '-', sizeof(underline));
+ underline[sizeof(underline) - 1] = '\0';
+
+ vty_out(vty, "\n");
+ vty_out(vty, "Showing statistics for pthread %s\n",
+ name);
+ vty_out(vty, "-------------------------------%s\n",
+ underline);
+ vty_out(vty, "%30s %18s %18s\n", "",
+ "CPU (user+system):", "Real (wall-clock):");
+ vty_out(vty,
+ "Active Runtime(ms) Invoked Avg uSec Max uSecs");
+ vty_out(vty, " Avg uSec Max uSecs");
+ vty_out(vty,
+ " CPU_Warn Wall_Warn Starv_Warn Type Thread\n");
+
+ if (m->cpu_record->count)
+ hash_iterate(
+ m->cpu_record,
+ (void (*)(struct hash_bucket *,
+ void *))cpu_record_hash_print,
+ args);
+ else
+ vty_out(vty, "No data to display yet.\n");
+
+ vty_out(vty, "\n");
+ }
+ }
+
+ vty_out(vty, "\n");
+ vty_out(vty, "Total thread statistics\n");
+ vty_out(vty, "-------------------------\n");
+ vty_out(vty, "%30s %18s %18s\n", "",
+ "CPU (user+system):", "Real (wall-clock):");
+ vty_out(vty, "Active Runtime(ms) Invoked Avg uSec Max uSecs");
+ vty_out(vty, " Avg uSec Max uSecs CPU_Warn Wall_Warn");
+ vty_out(vty, " Type Thread\n");
+
+ if (tmp.total_calls > 0)
+ vty_out_cpu_event_history(vty, &tmp);
+}
+
+static void cpu_record_hash_clear(struct hash_bucket *bucket, void *args[])
+{
+ uint8_t *filter = args[0];
+ struct hash *cpu_record = args[1];
+
+ struct cpu_event_history *a = bucket->data;
+
+ if (!(a->types & *filter))
+ return;
+
+ hash_release(cpu_record, bucket->data);
+}
+
+static void cpu_record_clear(uint8_t filter)
+{
+ uint8_t *tmp = &filter;
+ struct event_loop *m;
+ struct listnode *ln;
+
+ frr_with_mutex (&masters_mtx) {
+ for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) {
+ frr_with_mutex (&m->mtx) {
+ void *args[2] = {tmp, m->cpu_record};
+
+ hash_iterate(
+ m->cpu_record,
+ (void (*)(struct hash_bucket *,
+ void *))cpu_record_hash_clear,
+ args);
+ }
+ }
+ }
+}
+
+static uint8_t parse_filter(const char *filterstr)
+{
+ int i = 0;
+ int filter = 0;
+
+ while (filterstr[i] != '\0') {
+ switch (filterstr[i]) {
+ case 'r':
+ case 'R':
+ filter |= (1 << EVENT_READ);
+ break;
+ case 'w':
+ case 'W':
+ filter |= (1 << EVENT_WRITE);
+ break;
+ case 't':
+ case 'T':
+ filter |= (1 << EVENT_TIMER);
+ break;
+ case 'e':
+ case 'E':
+ filter |= (1 << EVENT_EVENT);
+ break;
+ case 'x':
+ case 'X':
+ filter |= (1 << EVENT_EXECUTE);
+ break;
+ default:
+ break;
+ }
+ ++i;
+ }
+ return filter;
+}
+
+DEFUN_NOSH (show_thread_cpu,
+ show_thread_cpu_cmd,
+ "show thread cpu [FILTER]",
+ SHOW_STR
+ "Thread information\n"
+ "Thread CPU usage\n"
+ "Display filter (rwtex)\n")
+{
+ uint8_t filter = (uint8_t)-1U;
+ int idx = 0;
+
+ if (argv_find(argv, argc, "FILTER", &idx)) {
+ filter = parse_filter(argv[idx]->arg);
+ if (!filter) {
+ vty_out(vty,
+ "Invalid filter \"%s\" specified; must contain at leastone of 'RWTEXB'\n",
+ argv[idx]->arg);
+ return CMD_WARNING;
+ }
+ }
+
+ cpu_record_print(vty, filter);
+ return CMD_SUCCESS;
+}
+
+DEFPY (service_cputime_stats,
+ service_cputime_stats_cmd,
+ "[no] service cputime-stats",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Collect CPU usage statistics\n")
+{
+ cputime_enabled = !no;
+ return CMD_SUCCESS;
+}
+
+DEFPY (service_cputime_warning,
+ service_cputime_warning_cmd,
+ "[no] service cputime-warning (1-4294967295)",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding CPU usage threshold\n"
+ "Warning threshold in milliseconds\n")
+{
+ if (no)
+ cputime_threshold = 0;
+ else
+ cputime_threshold = cputime_warning * 1000;
+ return CMD_SUCCESS;
+}
+
+ALIAS (service_cputime_warning,
+ no_service_cputime_warning_cmd,
+ "no service cputime-warning",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding CPU usage threshold\n")
+
+DEFPY (service_walltime_warning,
+ service_walltime_warning_cmd,
+ "[no] service walltime-warning (1-4294967295)",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding total wallclock threshold\n"
+ "Warning threshold in milliseconds\n")
+{
+ if (no)
+ walltime_threshold = 0;
+ else
+ walltime_threshold = walltime_warning * 1000;
+ return CMD_SUCCESS;
+}
+
+ALIAS (service_walltime_warning,
+ no_service_walltime_warning_cmd,
+ "no service walltime-warning",
+ NO_STR
+ "Set up miscellaneous service\n"
+ "Warn for tasks exceeding total wallclock threshold\n")
+
+static void show_thread_poll_helper(struct vty *vty, struct event_loop *m)
+{
+ const char *name = m->name ? m->name : "main";
+ char underline[strlen(name) + 1];
+ struct event *thread;
+ uint32_t i;
+
+ memset(underline, '-', sizeof(underline));
+ underline[sizeof(underline) - 1] = '\0';
+
+ vty_out(vty, "\nShowing poll FD's for %s\n", name);
+ vty_out(vty, "----------------------%s\n", underline);
+ vty_out(vty, "Count: %u/%d\n", (uint32_t)m->handler.pfdcount,
+ m->fd_limit);
+ for (i = 0; i < m->handler.pfdcount; i++) {
+ vty_out(vty, "\t%6d fd:%6d events:%2d revents:%2d\t\t", i,
+ m->handler.pfds[i].fd, m->handler.pfds[i].events,
+ m->handler.pfds[i].revents);
+
+ if (m->handler.pfds[i].events & POLLIN) {
+ thread = m->read[m->handler.pfds[i].fd];
+
+ if (!thread)
+ vty_out(vty, "ERROR ");
+ else
+ vty_out(vty, "%s ", thread->xref->funcname);
+ } else
+ vty_out(vty, " ");
+
+ if (m->handler.pfds[i].events & POLLOUT) {
+ thread = m->write[m->handler.pfds[i].fd];
+
+ if (!thread)
+ vty_out(vty, "ERROR\n");
+ else
+ vty_out(vty, "%s\n", thread->xref->funcname);
+ } else
+ vty_out(vty, "\n");
+ }
+}
+
+DEFUN_NOSH (show_thread_poll,
+ show_thread_poll_cmd,
+ "show thread poll",
+ SHOW_STR
+ "Thread information\n"
+ "Show poll FD's and information\n")
+{
+ struct listnode *node;
+ struct event_loop *m;
+
+ frr_with_mutex (&masters_mtx) {
+ for (ALL_LIST_ELEMENTS_RO(masters, node, m))
+ show_thread_poll_helper(vty, m);
+ }
+
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (clear_thread_cpu,
+ clear_thread_cpu_cmd,
+ "clear thread cpu [FILTER]",
+ "Clear stored data in all pthreads\n"
+ "Thread information\n"
+ "Thread CPU usage\n"
+ "Display filter (rwtexb)\n")
+{
+ uint8_t filter = (uint8_t)-1U;
+ int idx = 0;
+
+ if (argv_find(argv, argc, "FILTER", &idx)) {
+ filter = parse_filter(argv[idx]->arg);
+ if (!filter) {
+ vty_out(vty,
+ "Invalid filter \"%s\" specified; must contain at leastone of 'RWTEXB'\n",
+ argv[idx]->arg);
+ return CMD_WARNING;
+ }
+ }
+
+ cpu_record_clear(filter);
+ return CMD_SUCCESS;
+}
+
+static void show_thread_timers_helper(struct vty *vty, struct event_loop *m)
+{
+ const char *name = m->name ? m->name : "main";
+ char underline[strlen(name) + 1];
+ struct event *thread;
+
+ memset(underline, '-', sizeof(underline));
+ underline[sizeof(underline) - 1] = '\0';
+
+ vty_out(vty, "\nShowing timers for %s\n", name);
+ vty_out(vty, "-------------------%s\n", underline);
+
+ frr_each (event_timer_list, &m->timer, thread) {
+ vty_out(vty, " %-50s%pTH\n", thread->hist->funcname, thread);
+ }
+}
+
+DEFPY_NOSH (show_thread_timers,
+ show_thread_timers_cmd,
+ "show thread timers",
+ SHOW_STR
+ "Thread information\n"
+ "Show all timers and how long they have in the system\n")
+{
+ struct listnode *node;
+ struct event_loop *m;
+
+ frr_with_mutex (&masters_mtx) {
+ for (ALL_LIST_ELEMENTS_RO(masters, node, m))
+ show_thread_timers_helper(vty, m);
+ }
+
+ return CMD_SUCCESS;
+}
+
+void event_cmd_init(void)
+{
+ install_element(VIEW_NODE, &show_thread_cpu_cmd);
+ install_element(VIEW_NODE, &show_thread_poll_cmd);
+ install_element(ENABLE_NODE, &clear_thread_cpu_cmd);
+
+ install_element(CONFIG_NODE, &service_cputime_stats_cmd);
+ install_element(CONFIG_NODE, &service_cputime_warning_cmd);
+ install_element(CONFIG_NODE, &no_service_cputime_warning_cmd);
+ install_element(CONFIG_NODE, &service_walltime_warning_cmd);
+ install_element(CONFIG_NODE, &no_service_walltime_warning_cmd);
+
+ install_element(VIEW_NODE, &show_thread_timers_cmd);
+}
+/* CLI end ------------------------------------------------------------------ */
+
+
+static void cancelreq_del(void *cr)
+{
+ XFREE(MTYPE_TMP, cr);
+}
+
+/* initializer, only ever called once */
+static void initializer(void)
+{
+ pthread_key_create(&thread_current, NULL);
+}
+
+struct event_loop *event_master_create(const char *name)
+{
+ struct event_loop *rv;
+ struct rlimit limit;
+
+ pthread_once(&init_once, &initializer);
+
+ rv = XCALLOC(MTYPE_EVENT_MASTER, sizeof(struct event_loop));
+
+ /* Initialize master mutex */
+ pthread_mutex_init(&rv->mtx, NULL);
+ pthread_cond_init(&rv->cancel_cond, NULL);
+
+ /* Set name */
+ name = name ? name : "default";
+ rv->name = XSTRDUP(MTYPE_EVENT_MASTER, name);
+
+ /* Initialize I/O task data structures */
+
+ /* Use configured limit if present, ulimit otherwise. */
+ rv->fd_limit = frr_get_fd_limit();
+ if (rv->fd_limit == 0) {
+ getrlimit(RLIMIT_NOFILE, &limit);
+ rv->fd_limit = (int)limit.rlim_cur;
+ }
+
+ rv->read = XCALLOC(MTYPE_EVENT_POLL,
+ sizeof(struct event *) * rv->fd_limit);
+
+ rv->write = XCALLOC(MTYPE_EVENT_POLL,
+ sizeof(struct event *) * rv->fd_limit);
+
+ char tmhashname[strlen(name) + 32];
+
+ snprintf(tmhashname, sizeof(tmhashname), "%s - threadmaster event hash",
+ name);
+ rv->cpu_record = hash_create_size(
+ 8, (unsigned int (*)(const void *))cpu_record_hash_key,
+ (bool (*)(const void *, const void *))cpu_record_hash_cmp,
+ tmhashname);
+
+ event_list_init(&rv->event);
+ event_list_init(&rv->ready);
+ event_list_init(&rv->unuse);
+ event_timer_list_init(&rv->timer);
+
+ /* Initialize event_fetch() settings */
+ rv->spin = true;
+ rv->handle_signals = true;
+
+ /* Set pthread owner, should be updated by actual owner */
+ rv->owner = pthread_self();
+ rv->cancel_req = list_new();
+ rv->cancel_req->del = cancelreq_del;
+ rv->canceled = true;
+
+ /* Initialize pipe poker */
+ pipe(rv->io_pipe);
+ set_nonblocking(rv->io_pipe[0]);
+ set_nonblocking(rv->io_pipe[1]);
+
+ /* Initialize data structures for poll() */
+ rv->handler.pfdsize = rv->fd_limit;
+ rv->handler.pfdcount = 0;
+ rv->handler.pfds = XCALLOC(MTYPE_EVENT_MASTER,
+ sizeof(struct pollfd) * rv->handler.pfdsize);
+ rv->handler.copy = XCALLOC(MTYPE_EVENT_MASTER,
+ sizeof(struct pollfd) * rv->handler.pfdsize);
+
+ /* add to list of threadmasters */
+ frr_with_mutex (&masters_mtx) {
+ if (!masters)
+ masters = list_new();
+
+ listnode_add(masters, rv);
+ }
+
+ return rv;
+}
+
+void event_master_set_name(struct event_loop *master, const char *name)
+{
+ frr_with_mutex (&master->mtx) {
+ XFREE(MTYPE_EVENT_MASTER, master->name);
+ master->name = XSTRDUP(MTYPE_EVENT_MASTER, name);
+ }
+}
+
+#define EVENT_UNUSED_DEPTH 10
+
+/* Move thread to unuse list. */
+static void thread_add_unuse(struct event_loop *m, struct event *thread)
+{
+ pthread_mutex_t mtxc = thread->mtx;
+
+ assert(m != NULL && thread != NULL);
+
+ thread->hist->total_active--;
+ memset(thread, 0, sizeof(struct event));
+ thread->type = EVENT_UNUSED;
+
+ /* Restore the thread mutex context. */
+ thread->mtx = mtxc;
+
+ if (event_list_count(&m->unuse) < EVENT_UNUSED_DEPTH) {
+ event_list_add_tail(&m->unuse, thread);
+ return;
+ }
+
+ thread_free(m, thread);
+}
+
+/* Free all unused thread. */
+static void thread_list_free(struct event_loop *m, struct event_list_head *list)
+{
+ struct event *t;
+
+ while ((t = event_list_pop(list)))
+ thread_free(m, t);
+}
+
+static void thread_array_free(struct event_loop *m, struct event **thread_array)
+{
+ struct event *t;
+ int index;
+
+ for (index = 0; index < m->fd_limit; ++index) {
+ t = thread_array[index];
+ if (t) {
+ thread_array[index] = NULL;
+ thread_free(m, t);
+ }
+ }
+ XFREE(MTYPE_EVENT_POLL, thread_array);
+}
+
+/*
+ * event_master_free_unused
+ *
+ * As threads are finished with they are put on the
+ * unuse list for later reuse.
+ * If we are shutting down, Free up unused threads
+ * So we can see if we forget to shut anything off
+ */
+void event_master_free_unused(struct event_loop *m)
+{
+ frr_with_mutex (&m->mtx) {
+ struct event *t;
+
+ while ((t = event_list_pop(&m->unuse)))
+ thread_free(m, t);
+ }
+}
+
+/* Stop thread scheduler. */
+void event_master_free(struct event_loop *m)
+{
+ struct event *t;
+
+ frr_with_mutex (&masters_mtx) {
+ listnode_delete(masters, m);
+ if (masters->count == 0)
+ list_delete(&masters);
+ }
+
+ thread_array_free(m, m->read);
+ thread_array_free(m, m->write);
+ while ((t = event_timer_list_pop(&m->timer)))
+ thread_free(m, t);
+ thread_list_free(m, &m->event);
+ thread_list_free(m, &m->ready);
+ thread_list_free(m, &m->unuse);
+ pthread_mutex_destroy(&m->mtx);
+ pthread_cond_destroy(&m->cancel_cond);
+ close(m->io_pipe[0]);
+ close(m->io_pipe[1]);
+ list_delete(&m->cancel_req);
+ m->cancel_req = NULL;
+
+ hash_clean_and_free(&m->cpu_record, cpu_record_hash_free);
+
+ XFREE(MTYPE_EVENT_MASTER, m->name);
+ XFREE(MTYPE_EVENT_MASTER, m->handler.pfds);
+ XFREE(MTYPE_EVENT_MASTER, m->handler.copy);
+ XFREE(MTYPE_EVENT_MASTER, m);
+}
+
+/* Return remain time in milliseconds. */
+unsigned long event_timer_remain_msec(struct event *thread)
+{
+ int64_t remain;
+
+ if (!event_is_scheduled(thread))
+ return 0;
+
+ frr_with_mutex (&thread->mtx) {
+ remain = monotime_until(&thread->u.sands, NULL) / 1000LL;
+ }
+
+ return remain < 0 ? 0 : remain;
+}
+
+/* Return remain time in seconds. */
+unsigned long event_timer_remain_second(struct event *thread)
+{
+ return event_timer_remain_msec(thread) / 1000LL;
+}
+
+struct timeval event_timer_remain(struct event *thread)
+{
+ struct timeval remain;
+
+ frr_with_mutex (&thread->mtx) {
+ monotime_until(&thread->u.sands, &remain);
+ }
+ return remain;
+}
+
+static int time_hhmmss(char *buf, int buf_size, long sec)
+{
+ long hh;
+ long mm;
+ int wr;
+
+ assert(buf_size >= 8);
+
+ hh = sec / 3600;
+ sec %= 3600;
+ mm = sec / 60;
+ sec %= 60;
+
+ wr = snprintf(buf, buf_size, "%02ld:%02ld:%02ld", hh, mm, sec);
+
+ return wr != 8;
+}
+
+char *event_timer_to_hhmmss(char *buf, int buf_size, struct event *t_timer)
+{
+ if (t_timer)
+ time_hhmmss(buf, buf_size, event_timer_remain_second(t_timer));
+ else
+ snprintf(buf, buf_size, "--:--:--");
+
+ return buf;
+}
+
+/* Get new thread. */
+static struct event *thread_get(struct event_loop *m, uint8_t type,
+ void (*func)(struct event *), void *arg,
+ const struct xref_eventsched *xref)
+{
+ struct event *thread = event_list_pop(&m->unuse);
+ struct cpu_event_history tmp;
+
+ if (!thread) {
+ thread = XCALLOC(MTYPE_THREAD, sizeof(struct event));
+ /* mutex only needs to be initialized at struct creation. */
+ pthread_mutex_init(&thread->mtx, NULL);
+ m->alloc++;
+ }
+
+ thread->type = type;
+ thread->add_type = type;
+ thread->master = m;
+ thread->arg = arg;
+ thread->yield = EVENT_YIELD_TIME_SLOT; /* default */
+ thread->ref = NULL;
+ thread->ignore_timer_late = false;
+
+ /*
+ * So if the passed in funcname is not what we have
+ * stored that means the thread->hist needs to be
+ * updated. We keep the last one around in unused
+ * under the assumption that we are probably
+ * going to immediately allocate the same
+ * type of thread.
+ * This hopefully saves us some serious
+ * hash_get lookups.
+ */
+ if ((thread->xref && thread->xref->funcname != xref->funcname)
+ || thread->func != func) {
+ tmp.func = func;
+ tmp.funcname = xref->funcname;
+ thread->hist =
+ hash_get(m->cpu_record, &tmp,
+ (void *(*)(void *))cpu_record_hash_alloc);
+ }
+ thread->hist->total_active++;
+ thread->func = func;
+ thread->xref = xref;
+
+ return thread;
+}
+
+static void thread_free(struct event_loop *master, struct event *thread)
+{
+ /* Update statistics. */
+ assert(master->alloc > 0);
+ master->alloc--;
+
+ /* Free allocated resources. */
+ pthread_mutex_destroy(&thread->mtx);
+ XFREE(MTYPE_THREAD, thread);
+}
+
+static int fd_poll(struct event_loop *m, const struct timeval *timer_wait,
+ bool *eintr_p)
+{
+ sigset_t origsigs;
+ unsigned char trash[64];
+ nfds_t count = m->handler.copycount;
+
+ /*
+ * If timer_wait is null here, that means poll() should block
+ * indefinitely, unless the event_master has overridden it by setting
+ * ->selectpoll_timeout.
+ *
+ * If the value is positive, it specifies the maximum number of
+ * milliseconds to wait. If the timeout is -1, it specifies that
+ * we should never wait and always return immediately even if no
+ * event is detected. If the value is zero, the behavior is default.
+ */
+ int timeout = -1;
+
+ /* number of file descriptors with events */
+ int num;
+
+ if (timer_wait != NULL && m->selectpoll_timeout == 0) {
+ /* use the default value */
+ timeout = (timer_wait->tv_sec * 1000)
+ + (timer_wait->tv_usec / 1000);
+ } else if (m->selectpoll_timeout > 0) {
+ /* use the user's timeout */
+ timeout = m->selectpoll_timeout;
+ } else if (m->selectpoll_timeout < 0) {
+ /* effect a poll (return immediately) */
+ timeout = 0;
+ }
+
+ zlog_tls_buffer_flush();
+ rcu_read_unlock();
+ rcu_assert_read_unlocked();
+
+ /* add poll pipe poker */
+ assert(count + 1 < m->handler.pfdsize);
+ m->handler.copy[count].fd = m->io_pipe[0];
+ m->handler.copy[count].events = POLLIN;
+ m->handler.copy[count].revents = 0x00;
+
+ /* We need to deal with a signal-handling race here: we
+ * don't want to miss a crucial signal, such as SIGTERM or SIGINT,
+ * that may arrive just before we enter poll(). We will block the
+ * key signals, then check whether any have arrived - if so, we return
+ * before calling poll(). If not, we'll re-enable the signals
+ * in the ppoll() call.
+ */
+
+ sigemptyset(&origsigs);
+ if (m->handle_signals) {
+ /* Main pthread that handles the app signals */
+ if (frr_sigevent_check(&origsigs)) {
+ /* Signal to process - restore signal mask and return */
+ pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
+ num = -1;
+ *eintr_p = true;
+ goto done;
+ }
+ } else {
+ /* Don't make any changes for the non-main pthreads */
+ pthread_sigmask(SIG_SETMASK, NULL, &origsigs);
+ }
+
+#if defined(HAVE_PPOLL)
+ struct timespec ts, *tsp;
+
+ if (timeout >= 0) {
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ tsp = &ts;
+ } else
+ tsp = NULL;
+
+ num = ppoll(m->handler.copy, count + 1, tsp, &origsigs);
+ pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
+#else
+ /* Not ideal - there is a race after we restore the signal mask */
+ pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
+ num = poll(m->handler.copy, count + 1, timeout);
+#endif
+
+done:
+
+ if (num < 0 && errno == EINTR)
+ *eintr_p = true;
+
+ if (num > 0 && m->handler.copy[count].revents != 0 && num--)
+ while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0)
+ ;
+
+ rcu_read_lock();
+
+ return num;
+}
+
+/* Add new read thread. */
+void _event_add_read_write(const struct xref_eventsched *xref,
+ struct event_loop *m, void (*func)(struct event *),
+ void *arg, int fd, struct event **t_ptr)
+{
+ int dir = xref->event_type;
+ struct event *thread = NULL;
+ struct event **thread_array;
+
+ if (dir == EVENT_READ)
+ frrtrace(9, frr_libfrr, schedule_read, m,
+ xref->funcname, xref->xref.file, xref->xref.line,
+ t_ptr, fd, 0, arg, 0);
+ else
+ frrtrace(9, frr_libfrr, schedule_write, m,
+ xref->funcname, xref->xref.file, xref->xref.line,
+ t_ptr, fd, 0, arg, 0);
+
+ assert(fd >= 0);
+ if (fd >= m->fd_limit)
+ assert(!"Number of FD's open is greater than FRR currently configured to handle, aborting");
+
+ frr_with_mutex (&m->mtx) {
+ /* Thread is already scheduled; don't reschedule */
+ if (t_ptr && *t_ptr)
+ break;
+
+ /* default to a new pollfd */
+ nfds_t queuepos = m->handler.pfdcount;
+
+ if (dir == EVENT_READ)
+ thread_array = m->read;
+ else
+ thread_array = m->write;
+
+ /*
+ * if we already have a pollfd for our file descriptor, find and
+ * use it
+ */
+ for (nfds_t i = 0; i < m->handler.pfdcount; i++)
+ if (m->handler.pfds[i].fd == fd) {
+ queuepos = i;
+
+#ifdef DEV_BUILD
+ /*
+ * What happens if we have a thread already
+ * created for this event?
+ */
+ if (thread_array[fd])
+ assert(!"Thread already scheduled for file descriptor");
+#endif
+ break;
+ }
+
+ /* make sure we have room for this fd + pipe poker fd */
+ assert(queuepos + 1 < m->handler.pfdsize);
+
+ thread = thread_get(m, dir, func, arg, xref);
+
+ m->handler.pfds[queuepos].fd = fd;
+ m->handler.pfds[queuepos].events |=
+ (dir == EVENT_READ ? POLLIN : POLLOUT);
+
+ if (queuepos == m->handler.pfdcount)
+ m->handler.pfdcount++;
+
+ if (thread) {
+ frr_with_mutex (&thread->mtx) {
+ thread->u.fd = fd;
+ thread_array[thread->u.fd] = thread;
+ }
+
+ if (t_ptr) {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
+ }
+
+ AWAKEN(m);
+ }
+}
+
+static void _event_add_timer_timeval(const struct xref_eventsched *xref,
+ struct event_loop *m,
+ void (*func)(struct event *), void *arg,
+ struct timeval *time_relative,
+ struct event **t_ptr)
+{
+ struct event *thread;
+ struct timeval t;
+
+ assert(m != NULL);
+
+ assert(time_relative);
+
+ frrtrace(9, frr_libfrr, schedule_timer, m,
+ xref->funcname, xref->xref.file, xref->xref.line,
+ t_ptr, 0, 0, arg, (long)time_relative->tv_sec);
+
+ /* Compute expiration/deadline time. */
+ monotime(&t);
+ timeradd(&t, time_relative, &t);
+
+ frr_with_mutex (&m->mtx) {
+ if (t_ptr && *t_ptr)
+ /* thread is already scheduled; don't reschedule */
+ return;
+
+ thread = thread_get(m, EVENT_TIMER, func, arg, xref);
+
+ frr_with_mutex (&thread->mtx) {
+ thread->u.sands = t;
+ event_timer_list_add(&m->timer, thread);
+ if (t_ptr) {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
+ }
+
+ /* The timer list is sorted - if this new timer
+ * might change the time we'll wait for, give the pthread
+ * a chance to re-compute.
+ */
+ if (event_timer_list_first(&m->timer) == thread)
+ AWAKEN(m);
+ }
+#define ONEYEAR2SEC (60 * 60 * 24 * 365)
+ if (time_relative->tv_sec > ONEYEAR2SEC)
+ flog_err(
+ EC_LIB_TIMER_TOO_LONG,
+ "Timer: %pTHD is created with an expiration that is greater than 1 year",
+ thread);
+}
+
+
+/* Add timer event thread. */
+void _event_add_timer(const struct xref_eventsched *xref, struct event_loop *m,
+ void (*func)(struct event *), void *arg, long timer,
+ struct event **t_ptr)
+{
+ struct timeval trel;
+
+ assert(m != NULL);
+
+ trel.tv_sec = timer;
+ trel.tv_usec = 0;
+
+ _event_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
+}
+
+/* Add timer event thread with "millisecond" resolution */
+void _event_add_timer_msec(const struct xref_eventsched *xref,
+ struct event_loop *m, void (*func)(struct event *),
+ void *arg, long timer, struct event **t_ptr)
+{
+ struct timeval trel;
+
+ assert(m != NULL);
+
+ trel.tv_sec = timer / 1000;
+ trel.tv_usec = 1000 * (timer % 1000);
+
+ _event_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
+}
+
+/* Add timer event thread with "timeval" resolution */
+void _event_add_timer_tv(const struct xref_eventsched *xref,
+ struct event_loop *m, void (*func)(struct event *),
+ void *arg, struct timeval *tv, struct event **t_ptr)
+{
+ _event_add_timer_timeval(xref, m, func, arg, tv, t_ptr);
+}
+
+/* Add simple event thread. */
+void _event_add_event(const struct xref_eventsched *xref, struct event_loop *m,
+ void (*func)(struct event *), void *arg, int val,
+ struct event **t_ptr)
+{
+ struct event *thread = NULL;
+
+ frrtrace(9, frr_libfrr, schedule_event, m,
+ xref->funcname, xref->xref.file, xref->xref.line,
+ t_ptr, 0, val, arg, 0);
+
+ assert(m != NULL);
+
+ frr_with_mutex (&m->mtx) {
+ if (t_ptr && *t_ptr)
+ /* thread is already scheduled; don't reschedule */
+ break;
+
+ thread = thread_get(m, EVENT_EVENT, func, arg, xref);
+ frr_with_mutex (&thread->mtx) {
+ thread->u.val = val;
+ event_list_add_tail(&m->event, thread);
+ }
+
+ if (t_ptr) {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
+
+ AWAKEN(m);
+ }
+}
+
+/* Thread cancellation ------------------------------------------------------ */
+
+/**
+ * NOT's out the .events field of pollfd corresponding to the given file
+ * descriptor. The event to be NOT'd is passed in the 'state' parameter.
+ *
+ * This needs to happen for both copies of pollfd's. See 'event_fetch'
+ * implementation for details.
+ *
+ * @param master
+ * @param fd
+ * @param state the event to cancel. One or more (OR'd together) of the
+ * following:
+ * - POLLIN
+ * - POLLOUT
+ */
+static void event_cancel_rw(struct event_loop *master, int fd, short state,
+ int idx_hint)
+{
+ bool found = false;
+
+ /* find the index of corresponding pollfd */
+ nfds_t i;
+
+ /* Cancel POLLHUP too just in case some bozo set it */
+ state |= POLLHUP;
+
+ /* Some callers know the index of the pfd already */
+ if (idx_hint >= 0) {
+ i = idx_hint;
+ found = true;
+ } else {
+ /* Have to look for the fd in the pfd array */
+ for (i = 0; i < master->handler.pfdcount; i++)
+ if (master->handler.pfds[i].fd == fd) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ zlog_debug(
+ "[!] Received cancellation request for nonexistent rw job");
+ zlog_debug("[!] threadmaster: %s | fd: %d",
+ master->name ? master->name : "", fd);
+ return;
+ }
+
+ /* NOT out event. */
+ master->handler.pfds[i].events &= ~(state);
+
+ /* If all events are canceled, delete / resize the pollfd array. */
+ if (master->handler.pfds[i].events == 0) {
+ memmove(master->handler.pfds + i, master->handler.pfds + i + 1,
+ (master->handler.pfdcount - i - 1)
+ * sizeof(struct pollfd));
+ master->handler.pfdcount--;
+ master->handler.pfds[master->handler.pfdcount].fd = 0;
+ master->handler.pfds[master->handler.pfdcount].events = 0;
+ }
+
+ /*
+ * If we have the same pollfd in the copy, perform the same operations,
+ * otherwise return.
+ */
+ if (i >= master->handler.copycount)
+ return;
+
+ master->handler.copy[i].events &= ~(state);
+
+ if (master->handler.copy[i].events == 0) {
+ memmove(master->handler.copy + i, master->handler.copy + i + 1,
+ (master->handler.copycount - i - 1)
+ * sizeof(struct pollfd));
+ master->handler.copycount--;
+ master->handler.copy[master->handler.copycount].fd = 0;
+ master->handler.copy[master->handler.copycount].events = 0;
+ }
+}
+
+/*
+ * Process task cancellation given a task argument: iterate through the
+ * various lists of tasks, looking for any that match the argument.
+ */
+static void cancel_arg_helper(struct event_loop *master,
+ const struct cancel_req *cr)
+{
+ struct event *t;
+ nfds_t i;
+ int fd;
+ struct pollfd *pfd;
+
+ /* We're only processing arg-based cancellations here. */
+ if (cr->eventobj == NULL)
+ return;
+
+ /* First process the ready lists. */
+ frr_each_safe (event_list, &master->event, t) {
+ if (t->arg != cr->eventobj)
+ continue;
+ event_list_del(&master->event, t);
+ if (t->ref)
+ *t->ref = NULL;
+ thread_add_unuse(master, t);
+ }
+
+ frr_each_safe (event_list, &master->ready, t) {
+ if (t->arg != cr->eventobj)
+ continue;
+ event_list_del(&master->ready, t);
+ if (t->ref)
+ *t->ref = NULL;
+ thread_add_unuse(master, t);
+ }
+
+ /* If requested, stop here and ignore io and timers */
+ if (CHECK_FLAG(cr->flags, EVENT_CANCEL_FLAG_READY))
+ return;
+
+ /* Check the io tasks */
+ for (i = 0; i < master->handler.pfdcount;) {
+ pfd = master->handler.pfds + i;
+
+ if (pfd->events & POLLIN)
+ t = master->read[pfd->fd];
+ else
+ t = master->write[pfd->fd];
+
+ if (t && t->arg == cr->eventobj) {
+ fd = pfd->fd;
+
+ /* Found a match to cancel: clean up fd arrays */
+ event_cancel_rw(master, pfd->fd, pfd->events, i);
+
+ /* Clean up thread arrays */
+ master->read[fd] = NULL;
+ master->write[fd] = NULL;
+
+ /* Clear caller's ref */
+ if (t->ref)
+ *t->ref = NULL;
+
+ thread_add_unuse(master, t);
+
+ /* Don't increment 'i' since the cancellation will have
+ * removed the entry from the pfd array
+ */
+ } else
+ i++;
+ }
+
+ /* Check the timer tasks */
+ t = event_timer_list_first(&master->timer);
+ while (t) {
+ struct event *t_next;
+
+ t_next = event_timer_list_next(&master->timer, t);
+
+ if (t->arg == cr->eventobj) {
+ event_timer_list_del(&master->timer, t);
+ if (t->ref)
+ *t->ref = NULL;
+ thread_add_unuse(master, t);
+ }
+
+ t = t_next;
+ }
+}
+
+/**
+ * Process cancellation requests.
+ *
+ * This may only be run from the pthread which owns the event_master.
+ *
+ * @param master the thread master to process
+ * @REQUIRE master->mtx
+ */
+static void do_event_cancel(struct event_loop *master)
+{
+ struct event_list_head *list = NULL;
+ struct event **thread_array = NULL;
+ struct event *thread;
+ struct cancel_req *cr;
+ struct listnode *ln;
+
+ for (ALL_LIST_ELEMENTS_RO(master->cancel_req, ln, cr)) {
+ /*
+ * If this is an event object cancellation, search
+ * through task lists deleting any tasks which have the
+ * specified argument - use this handy helper function.
+ */
+ if (cr->eventobj) {
+ cancel_arg_helper(master, cr);
+ continue;
+ }
+
+ /*
+ * The pointer varies depending on whether the cancellation
+ * request was made asynchronously or not. If it was, we
+ * need to check whether the thread even exists anymore
+ * before cancelling it.
+ */
+ thread = (cr->thread) ? cr->thread : *cr->threadref;
+
+ if (!thread)
+ continue;
+
+ list = NULL;
+ thread_array = NULL;
+
+ /* Determine the appropriate queue to cancel the thread from */
+ switch (thread->type) {
+ case EVENT_READ:
+ event_cancel_rw(master, thread->u.fd, POLLIN, -1);
+ thread_array = master->read;
+ break;
+ case EVENT_WRITE:
+ event_cancel_rw(master, thread->u.fd, POLLOUT, -1);
+ thread_array = master->write;
+ break;
+ case EVENT_TIMER:
+ event_timer_list_del(&master->timer, thread);
+ break;
+ case EVENT_EVENT:
+ list = &master->event;
+ break;
+ case EVENT_READY:
+ list = &master->ready;
+ break;
+ case EVENT_UNUSED:
+ case EVENT_EXECUTE:
+ continue;
+ break;
+ }
+
+ if (list)
+ event_list_del(list, thread);
+ else if (thread_array)
+ thread_array[thread->u.fd] = NULL;
+
+ if (thread->ref)
+ *thread->ref = NULL;
+
+ thread_add_unuse(thread->master, thread);
+ }
+
+ /* Delete and free all cancellation requests */
+ if (master->cancel_req)
+ list_delete_all_node(master->cancel_req);
+
+ /* Wake up any threads which may be blocked in event_cancel_async() */
+ master->canceled = true;
+ pthread_cond_broadcast(&master->cancel_cond);
+}
+
+/*
+ * Helper function used for multiple flavors of arg-based cancellation.
+ */
+static void cancel_event_helper(struct event_loop *m, void *arg, int flags)
+{
+ struct cancel_req *cr;
+
+ assert(m->owner == pthread_self());
+
+ /* Only worth anything if caller supplies an arg. */
+ if (arg == NULL)
+ return;
+
+ cr = XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
+
+ cr->flags = flags;
+
+ frr_with_mutex (&m->mtx) {
+ cr->eventobj = arg;
+ listnode_add(m->cancel_req, cr);
+ do_event_cancel(m);
+ }
+}
+
+/**
+ * Cancel any events which have the specified argument.
+ *
+ * MT-Unsafe
+ *
+ * @param m the event_master to cancel from
+ * @param arg the argument passed when creating the event
+ */
+void event_cancel_event(struct event_loop *master, void *arg)
+{
+ cancel_event_helper(master, arg, 0);
+}
+
+/*
+ * Cancel ready tasks with an arg matching 'arg'
+ *
+ * MT-Unsafe
+ *
+ * @param m the event_master to cancel from
+ * @param arg the argument passed when creating the event
+ */
+void event_cancel_event_ready(struct event_loop *m, void *arg)
+{
+
+ /* Only cancel ready/event tasks */
+ cancel_event_helper(m, arg, EVENT_CANCEL_FLAG_READY);
+}
+
+/**
+ * Cancel a specific task.
+ *
+ * MT-Unsafe
+ *
+ * @param thread task to cancel
+ */
+void event_cancel(struct event **thread)
+{
+ struct event_loop *master;
+
+ if (thread == NULL || *thread == NULL)
+ return;
+
+ master = (*thread)->master;
+
+ frrtrace(9, frr_libfrr, event_cancel, master, (*thread)->xref->funcname,
+ (*thread)->xref->xref.file, (*thread)->xref->xref.line, NULL,
+ (*thread)->u.fd, (*thread)->u.val, (*thread)->arg,
+ (*thread)->u.sands.tv_sec);
+
+ assert(master->owner == pthread_self());
+
+ frr_with_mutex (&master->mtx) {
+ struct cancel_req *cr =
+ XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
+ cr->thread = *thread;
+ listnode_add(master->cancel_req, cr);
+ do_event_cancel(master);
+ }
+
+ *thread = NULL;
+}
+
+/**
+ * Asynchronous cancellation.
+ *
+ * Called with either a struct event ** or void * to an event argument,
+ * this function posts the correct cancellation request and blocks until it is
+ * serviced.
+ *
+ * If the thread is currently running, execution blocks until it completes.
+ *
+ * The last two parameters are mutually exclusive, i.e. if you pass one the
+ * other must be NULL.
+ *
+ * When the cancellation procedure executes on the target event_master, the
+ * thread * provided is checked for nullity. If it is null, the thread is
+ * assumed to no longer exist and the cancellation request is a no-op. Thus
+ * users of this API must pass a back-reference when scheduling the original
+ * task.
+ *
+ * MT-Safe
+ *
+ * @param master the thread master with the relevant event / task
+ * @param thread pointer to thread to cancel
+ * @param eventobj the event
+ */
+void event_cancel_async(struct event_loop *master, struct event **thread,
+ void *eventobj)
+{
+ assert(!(thread && eventobj) && (thread || eventobj));
+
+ if (thread && *thread)
+ frrtrace(9, frr_libfrr, event_cancel_async, master,
+ (*thread)->xref->funcname, (*thread)->xref->xref.file,
+ (*thread)->xref->xref.line, NULL, (*thread)->u.fd,
+ (*thread)->u.val, (*thread)->arg,
+ (*thread)->u.sands.tv_sec);
+ else
+ frrtrace(9, frr_libfrr, event_cancel_async, master, NULL, NULL,
+ 0, NULL, 0, 0, eventobj, 0);
+
+ assert(master->owner != pthread_self());
+
+ frr_with_mutex (&master->mtx) {
+ master->canceled = false;
+
+ if (thread) {
+ struct cancel_req *cr =
+ XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
+ cr->threadref = thread;
+ listnode_add(master->cancel_req, cr);
+ } else if (eventobj) {
+ struct cancel_req *cr =
+ XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
+ cr->eventobj = eventobj;
+ listnode_add(master->cancel_req, cr);
+ }
+ AWAKEN(master);
+
+ while (!master->canceled)
+ pthread_cond_wait(&master->cancel_cond, &master->mtx);
+ }
+
+ if (thread)
+ *thread = NULL;
+}
+/* ------------------------------------------------------------------------- */
+
+static struct timeval *thread_timer_wait(struct event_timer_list_head *timers,
+ struct timeval *timer_val)
+{
+ if (!event_timer_list_count(timers))
+ return NULL;
+
+ struct event *next_timer = event_timer_list_first(timers);
+
+ monotime_until(&next_timer->u.sands, timer_val);
+ return timer_val;
+}
+
+static struct event *thread_run(struct event_loop *m, struct event *thread,
+ struct event *fetch)
+{
+ *fetch = *thread;
+ thread_add_unuse(m, thread);
+ return fetch;
+}
+
+static int thread_process_io_helper(struct event_loop *m, struct event *thread,
+ short state, short actual_state, int pos)
+{
+ struct event **thread_array;
+
+ /*
+ * poll() clears the .events field, but the pollfd array we
+ * pass to poll() is a copy of the one used to schedule threads.
+ * We need to synchronize state between the two here by applying
+ * the same changes poll() made on the copy of the "real" pollfd
+ * array.
+ *
+ * This cleans up a possible infinite loop where we refuse
+ * to respond to a poll event but poll is insistent that
+ * we should.
+ */
+ m->handler.pfds[pos].events &= ~(state);
+
+ if (!thread) {
+ if ((actual_state & (POLLHUP|POLLIN)) != POLLHUP)
+ flog_err(EC_LIB_NO_THREAD,
+ "Attempting to process an I/O event but for fd: %d(%d) no thread to handle this!",
+ m->handler.pfds[pos].fd, actual_state);
+ return 0;
+ }
+
+ if (thread->type == EVENT_READ)
+ thread_array = m->read;
+ else
+ thread_array = m->write;
+
+ thread_array[thread->u.fd] = NULL;
+ event_list_add_tail(&m->ready, thread);
+ thread->type = EVENT_READY;
+
+ return 1;
+}
+
+/**
+ * Process I/O events.
+ *
+ * Walks through file descriptor array looking for those pollfds whose .revents
+ * field has something interesting. Deletes any invalid file descriptors.
+ *
+ * @param m the thread master
+ * @param num the number of active file descriptors (return value of poll())
+ */
+static void thread_process_io(struct event_loop *m, unsigned int num)
+{
+ unsigned int ready = 0;
+ struct pollfd *pfds = m->handler.copy;
+
+ for (nfds_t i = 0; i < m->handler.copycount && ready < num; ++i) {
+ /* no event for current fd? immediately continue */
+ if (pfds[i].revents == 0)
+ continue;
+
+ ready++;
+
+ /*
+ * Unless someone has called event_cancel from another
+ * pthread, the only thing that could have changed in
+ * m->handler.pfds while we were asleep is the .events
+ * field in a given pollfd. Barring event_cancel() that
+ * value should be a superset of the values we have in our
+ * copy, so there's no need to update it. Similarily,
+ * barring deletion, the fd should still be a valid index
+ * into the master's pfds.
+ *
+ * We are including POLLERR here to do a READ event
+ * this is because the read should fail and the
+ * read function should handle it appropriately
+ */
+ if (pfds[i].revents & (POLLIN | POLLHUP | POLLERR)) {
+ thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN,
+ pfds[i].revents, i);
+ }
+ if (pfds[i].revents & POLLOUT)
+ thread_process_io_helper(m, m->write[pfds[i].fd],
+ POLLOUT, pfds[i].revents, i);
+
+ /*
+ * if one of our file descriptors is garbage, remove the same
+ * from both pfds + update sizes and index
+ */
+ if (pfds[i].revents & POLLNVAL) {
+ memmove(m->handler.pfds + i, m->handler.pfds + i + 1,
+ (m->handler.pfdcount - i - 1)
+ * sizeof(struct pollfd));
+ m->handler.pfdcount--;
+ m->handler.pfds[m->handler.pfdcount].fd = 0;
+ m->handler.pfds[m->handler.pfdcount].events = 0;
+
+ memmove(pfds + i, pfds + i + 1,
+ (m->handler.copycount - i - 1)
+ * sizeof(struct pollfd));
+ m->handler.copycount--;
+ m->handler.copy[m->handler.copycount].fd = 0;
+ m->handler.copy[m->handler.copycount].events = 0;
+
+ i--;
+ }
+ }
+}
+
+/* Add all timers that have popped to the ready list. */
+static unsigned int thread_process_timers(struct event_loop *m,
+ struct timeval *timenow)
+{
+ struct timeval prev = *timenow;
+ bool displayed = false;
+ struct event *thread;
+ unsigned int ready = 0;
+
+ while ((thread = event_timer_list_first(&m->timer))) {
+ if (timercmp(timenow, &thread->u.sands, <))
+ break;
+ prev = thread->u.sands;
+ prev.tv_sec += 4;
+ /*
+ * If the timer would have popped 4 seconds in the
+ * past then we are in a situation where we are
+ * really getting behind on handling of events.
+ * Let's log it and do the right thing with it.
+ */
+ if (timercmp(timenow, &prev, >)) {
+ atomic_fetch_add_explicit(
+ &thread->hist->total_starv_warn, 1,
+ memory_order_seq_cst);
+ if (!displayed && !thread->ignore_timer_late) {
+ flog_warn(
+ EC_LIB_STARVE_THREAD,
+ "Thread Starvation: %pTHD was scheduled to pop greater than 4s ago",
+ thread);
+ displayed = true;
+ }
+ }
+
+ event_timer_list_pop(&m->timer);
+ thread->type = EVENT_READY;
+ event_list_add_tail(&m->ready, thread);
+ ready++;
+ }
+
+ return ready;
+}
+
+/* process a list en masse, e.g. for event thread lists */
+static unsigned int thread_process(struct event_list_head *list)
+{
+ struct event *thread;
+ unsigned int ready = 0;
+
+ while ((thread = event_list_pop(list))) {
+ thread->type = EVENT_READY;
+ event_list_add_tail(&thread->master->ready, thread);
+ ready++;
+ }
+ return ready;
+}
+
+
+/* Fetch next ready thread. */
+struct event *event_fetch(struct event_loop *m, struct event *fetch)
+{
+ struct event *thread = NULL;
+ struct timeval now;
+ struct timeval zerotime = {0, 0};
+ struct timeval tv;
+ struct timeval *tw = NULL;
+ bool eintr_p = false;
+ int num = 0;
+
+ do {
+ /* Handle signals if any */
+ if (m->handle_signals)
+ frr_sigevent_process();
+
+ pthread_mutex_lock(&m->mtx);
+
+ /* Process any pending cancellation requests */
+ do_event_cancel(m);
+
+ /*
+ * Attempt to flush ready queue before going into poll().
+ * This is performance-critical. Think twice before modifying.
+ */
+ if ((thread = event_list_pop(&m->ready))) {
+ fetch = thread_run(m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
+ pthread_mutex_unlock(&m->mtx);
+ if (!m->ready_run_loop)
+ GETRUSAGE(&m->last_getrusage);
+ m->ready_run_loop = true;
+ break;
+ }
+
+ m->ready_run_loop = false;
+ /* otherwise, tick through scheduling sequence */
+
+ /*
+ * Post events to ready queue. This must come before the
+ * following block since events should occur immediately
+ */
+ thread_process(&m->event);
+
+ /*
+ * If there are no tasks on the ready queue, we will poll()
+ * until a timer expires or we receive I/O, whichever comes
+ * first. The strategy for doing this is:
+ *
+ * - If there are events pending, set the poll() timeout to zero
+ * - If there are no events pending, but there are timers
+ * pending, set the timeout to the smallest remaining time on
+ * any timer.
+ * - If there are neither timers nor events pending, but there
+ * are file descriptors pending, block indefinitely in poll()
+ * - If nothing is pending, it's time for the application to die
+ *
+ * In every case except the last, we need to hit poll() at least
+ * once per loop to avoid starvation by events
+ */
+ if (!event_list_count(&m->ready))
+ tw = thread_timer_wait(&m->timer, &tv);
+
+ if (event_list_count(&m->ready) ||
+ (tw && !timercmp(tw, &zerotime, >)))
+ tw = &zerotime;
+
+ if (!tw && m->handler.pfdcount == 0) { /* die */
+ pthread_mutex_unlock(&m->mtx);
+ fetch = NULL;
+ break;
+ }
+
+ /*
+ * Copy pollfd array + # active pollfds in it. Not necessary to
+ * copy the array size as this is fixed.
+ */
+ m->handler.copycount = m->handler.pfdcount;
+ memcpy(m->handler.copy, m->handler.pfds,
+ m->handler.copycount * sizeof(struct pollfd));
+
+ pthread_mutex_unlock(&m->mtx);
+ {
+ eintr_p = false;
+ num = fd_poll(m, tw, &eintr_p);
+ }
+ pthread_mutex_lock(&m->mtx);
+
+ /* Handle any errors received in poll() */
+ if (num < 0) {
+ if (eintr_p) {
+ pthread_mutex_unlock(&m->mtx);
+ /* loop around to signal handler */
+ continue;
+ }
+
+ /* else die */
+ flog_err(EC_LIB_SYSTEM_CALL, "poll() error: %s",
+ safe_strerror(errno));
+ pthread_mutex_unlock(&m->mtx);
+ fetch = NULL;
+ break;
+ }
+
+ /* Post timers to ready queue. */
+ monotime(&now);
+ thread_process_timers(m, &now);
+
+ /* Post I/O to ready queue. */
+ if (num > 0)
+ thread_process_io(m, num);
+
+ pthread_mutex_unlock(&m->mtx);
+
+ } while (!thread && m->spin);
+
+ return fetch;
+}
+
+static unsigned long timeval_elapsed(struct timeval a, struct timeval b)
+{
+ return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
+ + (a.tv_usec - b.tv_usec));
+}
+
+unsigned long event_consumed_time(RUSAGE_T *now, RUSAGE_T *start,
+ unsigned long *cputime)
+{
+#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
+
+#ifdef __FreeBSD__
+ /*
+ * FreeBSD appears to have an issue when calling clock_gettime
+ * with CLOCK_THREAD_CPUTIME_ID really close to each other
+ * occassionally the now time will be before the start time.
+ * This is not good and FRR is ending up with CPU HOG's
+ * when the subtraction wraps to very large numbers
+ *
+ * What we are going to do here is cheat a little bit
+ * and notice that this is a problem and just correct
+ * it so that it is impossible to happen
+ */
+ if (start->cpu.tv_sec == now->cpu.tv_sec &&
+ start->cpu.tv_nsec > now->cpu.tv_nsec)
+ now->cpu.tv_nsec = start->cpu.tv_nsec + 1;
+ else if (start->cpu.tv_sec > now->cpu.tv_sec) {
+ now->cpu.tv_sec = start->cpu.tv_sec;
+ now->cpu.tv_nsec = start->cpu.tv_nsec + 1;
+ }
+#endif
+ *cputime = (now->cpu.tv_sec - start->cpu.tv_sec) * TIMER_SECOND_MICRO
+ + (now->cpu.tv_nsec - start->cpu.tv_nsec) / 1000;
+#else
+ /* This is 'user + sys' time. */
+ *cputime = timeval_elapsed(now->cpu.ru_utime, start->cpu.ru_utime)
+ + timeval_elapsed(now->cpu.ru_stime, start->cpu.ru_stime);
+#endif
+ return timeval_elapsed(now->real, start->real);
+}
+
+/*
+ * We should aim to yield after yield milliseconds, which defaults
+ * to EVENT_YIELD_TIME_SLOT .
+ * Note: we are using real (wall clock) time for this calculation.
+ * It could be argued that CPU time may make more sense in certain
+ * contexts. The things to consider are whether the thread may have
+ * blocked (in which case wall time increases, but CPU time does not),
+ * or whether the system is heavily loaded with other processes competing
+ * for CPU time. On balance, wall clock time seems to make sense.
+ * Plus it has the added benefit that gettimeofday should be faster
+ * than calling getrusage.
+ */
+int event_should_yield(struct event *thread)
+{
+ int result;
+
+ frr_with_mutex (&thread->mtx) {
+ result = monotime_since(&thread->real, NULL)
+ > (int64_t)thread->yield;
+ }
+ return result;
+}
+
+void event_set_yield_time(struct event *thread, unsigned long yield_time)
+{
+ frr_with_mutex (&thread->mtx) {
+ thread->yield = yield_time;
+ }
+}
+
+void event_getrusage(RUSAGE_T *r)
+{
+ monotime(&r->real);
+ if (!cputime_enabled) {
+ memset(&r->cpu, 0, sizeof(r->cpu));
+ return;
+ }
+
+#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
+ /* not currently implemented in Linux's vDSO, but maybe at some point
+ * in the future?
+ */
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &r->cpu);
+#else /* !HAVE_CLOCK_THREAD_CPUTIME_ID */
+#if defined RUSAGE_THREAD
+#define FRR_RUSAGE RUSAGE_THREAD
+#else
+#define FRR_RUSAGE RUSAGE_SELF
+#endif
+ getrusage(FRR_RUSAGE, &(r->cpu));
+#endif
+}
+
+/*
+ * Call a thread.
+ *
+ * This function will atomically update the thread's usage history. At present
+ * this is the only spot where usage history is written. Nevertheless the code
+ * has been written such that the introduction of writers in the future should
+ * not need to update it provided the writers atomically perform only the
+ * operations done here, i.e. updating the total and maximum times. In
+ * particular, the maximum real and cpu times must be monotonically increasing
+ * or this code is not correct.
+ */
+void event_call(struct event *thread)
+{
+ RUSAGE_T before, after;
+
+ /* if the thread being called is the CLI, it may change cputime_enabled
+ * ("service cputime-stats" command), which can result in nonsensical
+ * and very confusing warnings
+ */
+ bool cputime_enabled_here = cputime_enabled;
+
+ if (thread->master->ready_run_loop)
+ before = thread->master->last_getrusage;
+ else
+ GETRUSAGE(&before);
+
+ thread->real = before.real;
+
+ frrtrace(9, frr_libfrr, event_call, thread->master,
+ thread->xref->funcname, thread->xref->xref.file,
+ thread->xref->xref.line, NULL, thread->u.fd, thread->u.val,
+ thread->arg, thread->u.sands.tv_sec);
+
+ pthread_setspecific(thread_current, thread);
+ (*thread->func)(thread);
+ pthread_setspecific(thread_current, NULL);
+
+ GETRUSAGE(&after);
+ thread->master->last_getrusage = after;
+
+ unsigned long walltime, cputime;
+ unsigned long exp;
+
+ walltime = event_consumed_time(&after, &before, &cputime);
+
+ /* update walltime */
+ atomic_fetch_add_explicit(&thread->hist->real.total, walltime,
+ memory_order_seq_cst);
+ exp = atomic_load_explicit(&thread->hist->real.max,
+ memory_order_seq_cst);
+ while (exp < walltime
+ && !atomic_compare_exchange_weak_explicit(
+ &thread->hist->real.max, &exp, walltime,
+ memory_order_seq_cst, memory_order_seq_cst))
+ ;
+
+ if (cputime_enabled_here && cputime_enabled) {
+ /* update cputime */
+ atomic_fetch_add_explicit(&thread->hist->cpu.total, cputime,
+ memory_order_seq_cst);
+ exp = atomic_load_explicit(&thread->hist->cpu.max,
+ memory_order_seq_cst);
+ while (exp < cputime
+ && !atomic_compare_exchange_weak_explicit(
+ &thread->hist->cpu.max, &exp, cputime,
+ memory_order_seq_cst, memory_order_seq_cst))
+ ;
+ }
+
+ atomic_fetch_add_explicit(&thread->hist->total_calls, 1,
+ memory_order_seq_cst);
+ atomic_fetch_or_explicit(&thread->hist->types, 1 << thread->add_type,
+ memory_order_seq_cst);
+
+ if (cputime_enabled_here && cputime_enabled && cputime_threshold
+ && cputime > cputime_threshold) {
+ /*
+ * We have a CPU Hog on our hands. The time FRR has spent
+ * doing actual work (not sleeping) is greater than 5 seconds.
+ * Whinge about it now, so we're aware this is yet another task
+ * to fix.
+ */
+ atomic_fetch_add_explicit(&thread->hist->total_cpu_warn,
+ 1, memory_order_seq_cst);
+ flog_warn(
+ EC_LIB_SLOW_THREAD_CPU,
+ "CPU HOG: task %s (%lx) ran for %lums (cpu time %lums)",
+ thread->xref->funcname, (unsigned long)thread->func,
+ walltime / 1000, cputime / 1000);
+
+ } else if (walltime_threshold && walltime > walltime_threshold) {
+ /*
+ * The runtime for a task is greater than 5 seconds, but the
+ * cpu time is under 5 seconds. Let's whine about this because
+ * this could imply some sort of scheduling issue.
+ */
+ atomic_fetch_add_explicit(&thread->hist->total_wall_warn,
+ 1, memory_order_seq_cst);
+ flog_warn(
+ EC_LIB_SLOW_THREAD_WALL,
+ "STARVATION: task %s (%lx) ran for %lums (cpu time %lums)",
+ thread->xref->funcname, (unsigned long)thread->func,
+ walltime / 1000, cputime / 1000);
+ }
+}
+
+/* Execute thread */
+void _event_execute(const struct xref_eventsched *xref, struct event_loop *m,
+ void (*func)(struct event *), void *arg, int val)
+{
+ struct event *thread;
+
+ /* Get or allocate new thread to execute. */
+ frr_with_mutex (&m->mtx) {
+ thread = thread_get(m, EVENT_EVENT, func, arg, xref);
+
+ /* Set its event value. */
+ frr_with_mutex (&thread->mtx) {
+ thread->add_type = EVENT_EXECUTE;
+ thread->u.val = val;
+ thread->ref = &thread;
+ }
+ }
+
+ /* Execute thread doing all accounting. */
+ event_call(thread);
+
+ /* Give back or free thread. */
+ thread_add_unuse(m, thread);
+}
+
+/* Debug signal mask - if 'sigs' is NULL, use current effective mask. */
+void debug_signals(const sigset_t *sigs)
+{
+ int i, found;
+ sigset_t tmpsigs;
+ char buf[300];
+
+ /*
+ * We're only looking at the non-realtime signals here, so we need
+ * some limit value. Platform differences mean at some point we just
+ * need to pick a reasonable value.
+ */
+#if defined SIGRTMIN
+# define LAST_SIGNAL SIGRTMIN
+#else
+# define LAST_SIGNAL 32
+#endif
+
+
+ if (sigs == NULL) {
+ sigemptyset(&tmpsigs);
+ pthread_sigmask(SIG_BLOCK, NULL, &tmpsigs);
+ sigs = &tmpsigs;
+ }
+
+ found = 0;
+ buf[0] = '\0';
+
+ for (i = 0; i < LAST_SIGNAL; i++) {
+ char tmp[20];
+
+ if (sigismember(sigs, i) > 0) {
+ if (found > 0)
+ strlcat(buf, ",", sizeof(buf));
+ snprintf(tmp, sizeof(tmp), "%d", i);
+ strlcat(buf, tmp, sizeof(buf));
+ found++;
+ }
+ }
+
+ if (found == 0)
+ snprintf(buf, sizeof(buf), "<none>");
+
+ zlog_debug("%s: %s", __func__, buf);
+}
+
+static ssize_t printfrr_thread_dbg(struct fbuf *buf, struct printfrr_eargs *ea,
+ const struct event *thread)
+{
+ static const char *const types[] = {
+ [EVENT_READ] = "read", [EVENT_WRITE] = "write",
+ [EVENT_TIMER] = "timer", [EVENT_EVENT] = "event",
+ [EVENT_READY] = "ready", [EVENT_UNUSED] = "unused",
+ [EVENT_EXECUTE] = "exec",
+ };
+ ssize_t rv = 0;
+ char info[16] = "";
+
+ if (!thread)
+ return bputs(buf, "{(thread *)NULL}");
+
+ rv += bprintfrr(buf, "{(thread *)%p arg=%p", thread, thread->arg);
+
+ if (thread->type < array_size(types) && types[thread->type])
+ rv += bprintfrr(buf, " %-6s", types[thread->type]);
+ else
+ rv += bprintfrr(buf, " INVALID(%u)", thread->type);
+
+ switch (thread->type) {
+ case EVENT_READ:
+ case EVENT_WRITE:
+ snprintfrr(info, sizeof(info), "fd=%d", thread->u.fd);
+ break;
+
+ case EVENT_TIMER:
+ snprintfrr(info, sizeof(info), "r=%pTVMud", &thread->u.sands);
+ break;
+ case EVENT_READY:
+ case EVENT_EVENT:
+ case EVENT_UNUSED:
+ case EVENT_EXECUTE:
+ break;
+ }
+
+ rv += bprintfrr(buf, " %-12s %s() %s from %s:%d}", info,
+ thread->xref->funcname, thread->xref->dest,
+ thread->xref->xref.file, thread->xref->xref.line);
+ return rv;
+}
+
+printfrr_ext_autoreg_p("TH", printfrr_thread);
+static ssize_t printfrr_thread(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *ptr)
+{
+ const struct event *thread = ptr;
+ struct timespec remain = {};
+
+ if (ea->fmt[0] == 'D') {
+ ea->fmt++;
+ return printfrr_thread_dbg(buf, ea, thread);
+ }
+
+ if (!thread) {
+ /* need to jump over time formatting flag characters in the
+ * input format string, i.e. adjust ea->fmt!
+ */
+ printfrr_time(buf, ea, &remain,
+ TIMEFMT_TIMER_DEADLINE | TIMEFMT_SKIP);
+ return bputch(buf, '-');
+ }
+
+ TIMEVAL_TO_TIMESPEC(&thread->u.sands, &remain);
+ return printfrr_time(buf, ea, &remain, TIMEFMT_TIMER_DEADLINE);
+}
void log_ref_fini(void)
{
frr_with_mutex (&refs_mtx) {
- hash_clean(refs, NULL);
- hash_free(refs);
- refs = NULL;
+ hash_clean_and_free(&refs, NULL);
}
}
/* initialize mutex */
pthread_mutex_init(&fpt->mtx, NULL);
/* create new thread master */
- fpt->master = thread_master_create(name);
+ fpt->master = event_master_create(name);
/* set attributes */
fpt->attr = *attr;
name = (name ? name : "Anonymous thread");
static void frr_pthread_destroy_nolock(struct frr_pthread *fpt)
{
- thread_master_free(fpt->master);
+ event_master_free(fpt->master);
pthread_mutex_destroy(&fpt->mtx);
pthread_mutex_destroy(fpt->running_cond_mtx);
pthread_cond_destroy(fpt->running_cond);
*/
/* dummy task for sleeper pipe */
-static void fpt_dummy(struct thread *thread)
+static void fpt_dummy(struct event *thread)
{
}
/* poison pill task to end event loop */
-static void fpt_finish(struct thread *thread)
+static void fpt_finish(struct event *thread)
{
- struct frr_pthread *fpt = THREAD_ARG(thread);
+ struct frr_pthread *fpt = EVENT_ARG(thread);
atomic_store_explicit(&fpt->running, false, memory_order_relaxed);
}
/* stop function, called from other threads to halt this one */
static int fpt_halt(struct frr_pthread *fpt, void **res)
{
- thread_add_event(fpt->master, &fpt_finish, fpt, 0, NULL);
+ event_add_event(fpt->master, &fpt_finish, fpt, 0, NULL);
pthread_join(fpt->thread, res);
return 0;
int sleeper[2];
pipe(sleeper);
- thread_add_read(fpt->master, &fpt_dummy, NULL, sleeper[0], NULL);
+ event_add_read(fpt->master, &fpt_dummy, NULL, sleeper[0], NULL);
fpt->master->handle_signals = false;
frr_pthread_notify_running(fpt);
- struct thread task;
+ struct event task;
while (atomic_load_explicit(&fpt->running, memory_order_relaxed)) {
pthread_testcancel();
- if (thread_fetch(fpt->master, &task)) {
- thread_call(&task);
+ if (event_fetch(fpt->master, &task)) {
+ event_call(&task);
}
}
#include "frratomic.h"
#include "memory.h"
#include "frrcu.h"
-#include "thread.h"
+#include "frrevent.h"
#ifdef __cplusplus
extern "C" {
struct rcu_thread *rcu_thread;
/* thread master for this pthread's thread.c event loop */
- struct thread_master *master;
+ struct event_loop *master;
/* caller-specified data; start & stop funcs, name, id */
struct frr_pthread_attr attr;
#include <zebra.h>
#include <zmq.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "frr_zmq.h"
#include "log.h"
}
}
-static void frrzmq_read_msg(struct thread *t)
+static void frrzmq_read_msg(struct event *t)
{
- struct frrzmq_cb **cbp = THREAD_ARG(t);
+ struct frrzmq_cb **cbp = EVENT_ARG(t);
struct frrzmq_cb *cb;
zmq_msg_t msg;
unsigned partno;
if (read)
frrzmq_check_events(cbp, &cb->write, ZMQ_POLLOUT);
- thread_add_read(t->master, frrzmq_read_msg, cbp,
- cb->fd, &cb->read.thread);
+ event_add_read(t->master, frrzmq_read_msg, cbp, cb->fd,
+ &cb->read.thread);
return;
out_err:
cb->read.cb_error(cb->read.arg, cb->zmqsock);
}
-int _frrzmq_thread_add_read(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*msgfunc)(void *arg, void *zmqsock),
- void (*partfunc)(void *arg, void *zmqsock,
- zmq_msg_t *msg, unsigned partnum),
- void (*errfunc)(void *arg, void *zmqsock),
- void *arg, void *zmqsock,
- struct frrzmq_cb **cbp)
+int _frrzmq_event_add_read(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*msgfunc)(void *arg, void *zmqsock),
+ void (*partfunc)(void *arg, void *zmqsock,
+ zmq_msg_t *msg, unsigned partnum),
+ void (*errfunc)(void *arg, void *zmqsock), void *arg,
+ void *zmqsock, struct frrzmq_cb **cbp)
{
int fd, events;
size_t len;
cb->in_cb = false;
if (events & ZMQ_POLLIN) {
- thread_cancel(&cb->read.thread);
+ event_cancel(&cb->read.thread);
- thread_add_event(master, frrzmq_read_msg, cbp, fd,
- &cb->read.thread);
- } else
- thread_add_read(master, frrzmq_read_msg, cbp, fd,
+ event_add_event(master, frrzmq_read_msg, cbp, fd,
&cb->read.thread);
+ } else
+ event_add_read(master, frrzmq_read_msg, cbp, fd,
+ &cb->read.thread);
return 0;
}
-static void frrzmq_write_msg(struct thread *t)
+static void frrzmq_write_msg(struct event *t)
{
- struct frrzmq_cb **cbp = THREAD_ARG(t);
+ struct frrzmq_cb **cbp = EVENT_ARG(t);
struct frrzmq_cb *cb;
unsigned char written = 0;
int ret;
if (written)
frrzmq_check_events(cbp, &cb->read, ZMQ_POLLIN);
- thread_add_write(t->master, frrzmq_write_msg, cbp,
- cb->fd, &cb->write.thread);
+ event_add_write(t->master, frrzmq_write_msg, cbp, cb->fd,
+ &cb->write.thread);
return;
out_err:
cb->write.cb_error(cb->write.arg, cb->zmqsock);
}
-int _frrzmq_thread_add_write(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*msgfunc)(void *arg, void *zmqsock),
- void (*errfunc)(void *arg, void *zmqsock),
- void *arg, void *zmqsock, struct frrzmq_cb **cbp)
+int _frrzmq_event_add_write(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*msgfunc)(void *arg, void *zmqsock),
+ void (*errfunc)(void *arg, void *zmqsock),
+ void *arg, void *zmqsock, struct frrzmq_cb **cbp)
{
int fd, events;
size_t len;
cb->in_cb = false;
if (events & ZMQ_POLLOUT) {
- thread_cancel(&cb->write.thread);
+ event_cancel(&cb->write.thread);
- _thread_add_event(xref, master, frrzmq_write_msg, cbp, fd,
- &cb->write.thread);
- } else
- thread_add_write(master, frrzmq_write_msg, cbp, fd,
+ _event_add_event(xref, master, frrzmq_write_msg, cbp, fd,
&cb->write.thread);
+ } else
+ event_add_write(master, frrzmq_write_msg, cbp, fd,
+ &cb->write.thread);
return 0;
}
if (!cb || !*cb)
return;
core->cancelled = true;
- thread_cancel(&core->thread);
+ event_cancel(&core->thread);
/* If cancelled from within a callback, don't try to free memory
* in this path.
if (zmq_getsockopt(cb->zmqsock, ZMQ_EVENTS, &events, &len))
return;
if ((events & event) && core->thread && !core->cancelled) {
- struct thread_master *tm = core->thread->master;
+ struct event_loop *tm = core->thread->master;
- thread_cancel(&core->thread);
+ event_cancel(&core->thread);
if (event == ZMQ_POLLIN)
- thread_add_event(tm, frrzmq_read_msg,
- cbp, cb->fd, &core->thread);
+ event_add_event(tm, frrzmq_read_msg, cbp, cb->fd,
+ &core->thread);
else
- thread_add_event(tm, frrzmq_write_msg,
- cbp, cb->fd, &core->thread);
+ event_add_event(tm, frrzmq_write_msg, cbp, cb->fd,
+ &core->thread);
}
}
#ifndef _FRRZMQ_H
#define _FRRZMQ_H
-#include "thread.h"
+#include "frrevent.h"
#include <zmq.h>
#ifdef __cplusplus
/* callback integration */
struct cb_core {
- struct thread *thread;
+ struct event *thread;
void *arg;
bool cancelled;
#define _xref_zmq_a(type, f, d, call) \
({ \
- static const struct xref_threadsched _xref \
- __attribute__((used)) = { \
- .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
+ static const struct xref_eventsched _xref __attribute__( \
+ (used)) = { \
+ .xref = XREF_INIT(XREFT_EVENTSCHED, NULL, __func__), \
.funcname = #f, \
.dest = #d, \
- .thread_type = THREAD_ ## type, \
+ .event_type = EVENT_##type, \
}; \
XREF_LINK(_xref.xref); \
call; \
- }) \
- /* end */
+ }) /* end */
/* core event registration, one of these 2 macros should be used */
-#define frrzmq_thread_add_read_msg(m, f, e, a, z, d) \
+#define frrzmq_event_add_read_msg(m, f, e, a, z, d) \
_xref_zmq_a(READ, f, d, \
- _frrzmq_thread_add_read(&_xref, m, f, NULL, e, a, z, d))
+ _frrzmq_event_add_read(&_xref, m, f, NULL, e, a, z, d))
-#define frrzmq_thread_add_read_part(m, f, e, a, z, d) \
+#define frrzmq_event_add_read_part(m, f, e, a, z, d) \
_xref_zmq_a(READ, f, d, \
- _frrzmq_thread_add_read(&_xref, m, NULL, f, e, a, z, d))
+ _frrzmq_event_add_read(&_xref, m, NULL, f, e, a, z, d))
-#define frrzmq_thread_add_write_msg(m, f, e, a, z, d) \
+#define frrzmq_event_add_write_msg(m, f, e, a, z, d) \
_xref_zmq_a(WRITE, f, d, \
- _frrzmq_thread_add_write(&_xref, m, f, e, a, z, d))
+ _frrzmq_event_add_write(&_xref, m, f, e, a, z, d))
struct cb_core;
struct frrzmq_cb;
* may schedule the event to run as soon as libfrr is back in its main
* loop.
*/
-extern int _frrzmq_thread_add_read(
- const struct xref_threadsched *xref, struct thread_master *master,
- void (*msgfunc)(void *arg, void *zmqsock),
- void (*partfunc)(void *arg, void *zmqsock, zmq_msg_t *msg,
- unsigned partnum),
- void (*errfunc)(void *arg, void *zmqsock), void *arg, void *zmqsock,
- struct frrzmq_cb **cb);
-extern int _frrzmq_thread_add_write(
- const struct xref_threadsched *xref, struct thread_master *master,
- void (*msgfunc)(void *arg, void *zmqsock),
- void (*errfunc)(void *arg, void *zmqsock), void *arg, void *zmqsock,
- struct frrzmq_cb **cb);
+extern int
+_frrzmq_event_add_read(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*msgfunc)(void *arg, void *zmqsock),
+ void (*partfunc)(void *arg, void *zmqsock,
+ zmq_msg_t *msg, unsigned partnum),
+ void (*errfunc)(void *arg, void *zmqsock), void *arg,
+ void *zmqsock, struct frrzmq_cb **cb);
+extern int _frrzmq_event_add_write(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*msgfunc)(void *arg, void *zmqsock),
+ void (*errfunc)(void *arg, void *zmqsock),
+ void *arg, void *zmqsock,
+ struct frrzmq_cb **cb);
extern void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core);
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Event management routine header.
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ */
+
+#ifndef _ZEBRA_THREAD_H
+#define _ZEBRA_THREAD_H
+
+#include <zebra.h>
+#include <pthread.h>
+#include <poll.h>
+#include "monotime.h"
+#include "frratomic.h"
+#include "typesafe.h"
+#include "xref.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern bool cputime_enabled;
+extern unsigned long cputime_threshold;
+/* capturing wallclock time is always enabled since it is fast (reading
+ * hardware TSC w/o syscalls)
+ */
+extern unsigned long walltime_threshold;
+
+struct rusage_t {
+#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
+ struct timespec cpu;
+#else
+ struct rusage cpu;
+#endif
+ struct timeval real;
+};
+#define RUSAGE_T struct rusage_t
+
+#define GETRUSAGE(X) event_getrusage(X)
+
+PREDECL_LIST(event_list);
+PREDECL_HEAP(event_timer_list);
+
+struct fd_handler {
+ /* number of pfd that fit in the allocated space of pfds. This is a
+ * constant and is the same for both pfds and copy.
+ */
+ nfds_t pfdsize;
+
+ /* file descriptors to monitor for i/o */
+ struct pollfd *pfds;
+ /* number of pollfds stored in pfds */
+ nfds_t pfdcount;
+
+ /* chunk used for temp copy of pollfds */
+ struct pollfd *copy;
+ /* number of pollfds stored in copy */
+ nfds_t copycount;
+};
+
+struct xref_eventsched {
+ struct xref xref;
+
+ const char *funcname;
+ const char *dest;
+ uint32_t event_type;
+};
+
+/* Master of the theads. */
+struct event_loop {
+ char *name;
+
+ struct event **read;
+ struct event **write;
+ struct event_timer_list_head timer;
+ struct event_list_head event, ready, unuse;
+ struct list *cancel_req;
+ bool canceled;
+ pthread_cond_t cancel_cond;
+ struct hash *cpu_record;
+ int io_pipe[2];
+ int fd_limit;
+ struct fd_handler handler;
+ unsigned long alloc;
+ long selectpoll_timeout;
+ bool spin;
+ bool handle_signals;
+ pthread_mutex_t mtx;
+ pthread_t owner;
+
+ bool ready_run_loop;
+ RUSAGE_T last_getrusage;
+};
+
+/* Event types. */
+enum event_types {
+ EVENT_READ,
+ EVENT_WRITE,
+ EVENT_TIMER,
+ EVENT_EVENT,
+ EVENT_READY,
+ EVENT_UNUSED,
+ EVENT_EXECUTE,
+};
+
+/* Event itself. */
+struct event {
+ enum event_types type; /* event type */
+ enum event_types add_type; /* event type */
+ struct event_list_item eventitem;
+ struct event_timer_list_item timeritem;
+ struct event **ref; /* external reference (if given) */
+ struct event_loop *master; /* pointer to the struct event_loop */
+ void (*func)(struct event *e); /* event function */
+ void *arg; /* event argument */
+ union {
+ int val; /* second argument of the event. */
+ int fd; /* file descriptor in case of r/w */
+ struct timeval sands; /* rest of time sands value. */
+ } u;
+ struct timeval real;
+ struct cpu_event_history *hist; /* cache pointer to cpu_history */
+ unsigned long yield; /* yield time in microseconds */
+ const struct xref_eventsched *xref; /* origin location */
+ pthread_mutex_t mtx; /* mutex for thread.c functions */
+ bool ignore_timer_late;
+};
+
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+#pragma FRR printfrr_ext "%pTH"(struct event *)
+#endif
+
+struct cpu_event_history {
+ void (*func)(struct event *e);
+ atomic_size_t total_cpu_warn;
+ atomic_size_t total_wall_warn;
+ atomic_size_t total_starv_warn;
+ atomic_size_t total_calls;
+ atomic_size_t total_active;
+ struct time_stats {
+ atomic_size_t total, max;
+ } real;
+ struct time_stats cpu;
+ atomic_uint_fast32_t types;
+ const char *funcname;
+};
+
+/* Struct timeval's tv_usec one second value. */
+#define TIMER_SECOND_MICRO 1000000L
+
+/* Event yield time. */
+#define EVENT_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
+
+#define EVENT_TIMER_STRLEN 12
+
+/* Macros. */
+#define EVENT_ARG(X) ((X)->arg)
+#define EVENT_FD(X) ((X)->u.fd)
+#define EVENT_VAL(X) ((X)->u.val)
+
+/*
+ * Please consider this macro deprecated, and do not use it in new code.
+ */
+#define EVENT_OFF(thread) \
+ do { \
+ if ((thread)) \
+ event_cancel(&(thread)); \
+ } while (0)
+
+/*
+ * Macro wrappers to generate xrefs for all thread add calls. Includes
+ * file/line/function info for debugging/tracing.
+ */
+#include "lib/xref.h"
+
+#define _xref_t_a(addfn, type, m, f, a, v, t) \
+ ({ \
+ static const struct xref_eventsched _xref __attribute__( \
+ (used)) = { \
+ .xref = XREF_INIT(XREFT_EVENTSCHED, NULL, __func__), \
+ .funcname = #f, \
+ .dest = #t, \
+ .event_type = EVENT_##type, \
+ }; \
+ XREF_LINK(_xref.xref); \
+ _event_add_##addfn(&_xref, m, f, a, v, t); \
+ }) /* end */
+
+#define event_add_read(m, f, a, v, t) _xref_t_a(read_write, READ, m, f, a, v, t)
+#define event_add_write(m, f, a, v, t) \
+ _xref_t_a(read_write, WRITE, m, f, a, v, t)
+#define event_add_timer(m, f, a, v, t) _xref_t_a(timer, TIMER, m, f, a, v, t)
+#define event_add_timer_msec(m, f, a, v, t) \
+ _xref_t_a(timer_msec, TIMER, m, f, a, v, t)
+#define event_add_timer_tv(m, f, a, v, t) \
+ _xref_t_a(timer_tv, TIMER, m, f, a, v, t)
+#define event_add_event(m, f, a, v, t) _xref_t_a(event, EVENT, m, f, a, v, t)
+
+#define event_execute(m, f, a, v) \
+ ({ \
+ static const struct xref_eventsched _xref __attribute__( \
+ (used)) = { \
+ .xref = XREF_INIT(XREFT_EVENTSCHED, NULL, __func__), \
+ .funcname = #f, \
+ .dest = NULL, \
+ .event_type = EVENT_EXECUTE, \
+ }; \
+ XREF_LINK(_xref.xref); \
+ _event_execute(&_xref, m, f, a, v); \
+ }) /* end */
+
+/* Prototypes. */
+extern struct event_loop *event_master_create(const char *name);
+void event_master_set_name(struct event_loop *master, const char *name);
+extern void event_master_free(struct event_loop *m);
+extern void event_master_free_unused(struct event_loop *m);
+
+extern void _event_add_read_write(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*fn)(struct event *), void *arg, int fd,
+ struct event **tref);
+
+extern void _event_add_timer(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*fn)(struct event *), void *arg, long t,
+ struct event **tref);
+
+extern void _event_add_timer_msec(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*fn)(struct event *), void *arg, long t,
+ struct event **tref);
+
+extern void _event_add_timer_tv(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*fn)(struct event *), void *arg,
+ struct timeval *tv, struct event **tref);
+
+extern void _event_add_event(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*fn)(struct event *), void *arg, int val,
+ struct event **tref);
+
+extern void _event_execute(const struct xref_eventsched *xref,
+ struct event_loop *master,
+ void (*fn)(struct event *), void *arg, int val);
+
+extern void event_cancel(struct event **event);
+extern void event_cancel_async(struct event_loop *m, struct event **eptr,
+ void *data);
+/* Cancel ready tasks with an arg matching 'arg' */
+extern void event_cancel_event_ready(struct event_loop *m, void *arg);
+/* Cancel all tasks with an arg matching 'arg', including timers and io */
+extern void event_cancel_event(struct event_loop *m, void *arg);
+extern struct event *event_fetch(struct event_loop *m, struct event *event);
+extern void event_call(struct event *event);
+extern unsigned long event_timer_remain_second(struct event *event);
+extern struct timeval event_timer_remain(struct event *event);
+extern unsigned long event_timer_remain_msec(struct event *event);
+extern int event_should_yield(struct event *event);
+/* set yield time for thread */
+extern void event_set_yield_time(struct event *event, unsigned long ytime);
+
+/* Internal libfrr exports */
+extern void event_getrusage(RUSAGE_T *r);
+extern void event_cmd_init(void);
+
+/* Returns elapsed real (wall clock) time. */
+extern unsigned long event_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
+ unsigned long *cpu_time_elapsed);
+
+/* only for use in logging functions! */
+extern pthread_key_t thread_current;
+extern char *event_timer_to_hhmmss(char *buf, int buf_size,
+ struct event *t_timer);
+
+static inline bool event_is_scheduled(struct event *thread)
+{
+ if (thread)
+ return true;
+
+ return false;
+}
+
+/* Debug signal mask */
+void debug_signals(const sigset_t *sigs);
+
+static inline void event_ignore_late_timer(struct event *event)
+{
+ event->ignore_timer_late = true;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZEBRA_THREAD_H */
void frrscript_delete(struct frrscript *fs)
{
- hash_clean(fs->lua_function_hash, lua_function_free);
- hash_free(fs->lua_function_hash);
+ hash_clean_and_free(&fs->lua_function_hash, lua_function_free);
XFREE(MTYPE_SCRIPT, fs->name);
XFREE(MTYPE_SCRIPT, fs);
}
void frrscript_fini(void)
{
- hash_clean(codec_hash, codec_free);
- hash_free(codec_hash);
+ hash_clean_and_free(&codec_hash, codec_free);
frrscript_names_destroy();
}
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* Getopt for GNU.
- * NOTE: getopt is now part of the C library, so if you don't know what
- * "Keep this file name-space clean" means, talk to drepper@gnu.org
- * before changing it!
- *
- * Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
- * Free Software Foundation, Inc.
- *
- * NOTE: The canonical source of this file is maintained with the GNU C Library.
- * Bugs can be reported to bug-glibc@gnu.org.
- */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
- Ditto for AIX 3.2 and <stdlib.h>. */
-#ifndef _NO_PROTO
-# define _NO_PROTO
-#endif
-
-#include <zebra.h>
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-# define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-# define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#include <unistd.h>
-#endif /* GNU C library. */
-
-#ifdef VMS
-#include <unixlib.h>
-#if HAVE_STRING_H - 0
-#include <string.h>
-#endif
-#endif
-
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.
- When compiling libc, the _ macro is predefined. */
-#ifdef HAVE_LIBINTL_H
-#include <libintl.h>
-# define _(msgid) gettext (msgid)
-#else
-# define _(msgid) (msgid)
-#endif
-#endif
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = NULL;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* Formerly, initialization of getopt depended on optind==0, which
- causes problems with re-calling getopt as programs generally don't
- know that. */
-
-int __getopt_initialized = 0;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return -1 with `optind' != ARGC. */
-
-static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
-
-/* Value of POSIXLY_CORRECT environment variable. */
-static char *posixly_correct;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-#include <string.h>
-# define my_index strchr
-#else
-
-#if HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-#ifndef getenv
-extern char *getenv(const char *);
-#endif
-
-static char *my_index(const char *str, int chr)
-{
- while (*str) {
- if (*str == chr)
- return (char *)str;
- str++;
- }
- return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
- If not using GCC, it is ok not to declare it. */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
- That was relevant to code that was here before. */
-#if (!defined __STDC__ || !__STDC__) && !defined strlen
-/* gcc with -traditional declares the built-in strlen to return int,
- and has done so at least since version 2.4.5. -- rms. */
-extern int strlen(const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-#ifdef _LIBC
-/* Bash 2.0 gives us an environment variable containing flags
- indicating ARGV elements that should not be considered arguments. */
-
-/* Defined in getopt_init.c */
-extern char *__getopt_nonoption_flags;
-
-static int nonoption_flags_max_len;
-static int nonoption_flags_len;
-
-static int original_argc;
-static char *const *original_argv;
-
-/* Make sure the environment variable bash 2.0 puts in the environment
- is valid for the getopt call we must make sure that the ARGV passed
- to getopt is that one passed to the process. */
-static void __attribute__((unused))
-store_args_and_env(int argc, char *const *argv)
-{
- /* XXX This is no good solution. We should rather copy the args so
- that we can compare them later. But we must not use malloc(3). */
- original_argc = argc;
- original_argv = argv;
-}
-#ifdef text_set_element
-text_set_element(__libc_subinit, store_args_and_env);
-#endif /* text_set_element */
-
-#define SWAP_FLAGS(ch1, ch2) \
- if (nonoption_flags_len > 0) { \
- char __tmp = __getopt_nonoption_flags[ch1]; \
- __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
- __getopt_nonoption_flags[ch2] = __tmp; \
- }
-#else /* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif /* _LIBC */
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-#if defined __STDC__ && __STDC__
-static void exchange(char **);
-#endif
-
-static void exchange(argv) char **argv;
-{
- int bottom = first_nonopt;
- int middle = last_nonopt;
- int top = optind;
- char *tem;
-
-/* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
-#ifdef _LIBC
- /* First make sure the handling of the `__getopt_nonoption_flags'
- string can work normally. Our top argument must be in the range
- of the string. */
- if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) {
- /* We must extend the array. The user plays games with us and
- presents new arguments. */
- char *new_str = malloc(top + 1);
- if (new_str == NULL)
- nonoption_flags_len = nonoption_flags_max_len = 0;
- else {
- memset(__mempcpy(new_str, __getopt_nonoption_flags,
- nonoption_flags_max_len),
- '\0', top + 1 - nonoption_flags_max_len);
- nonoption_flags_max_len = top + 1;
- __getopt_nonoption_flags = new_str;
- }
- }
-#endif
-
- while (top > middle && middle > bottom) {
- if (top - middle > middle - bottom) {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++) {
- tem = argv[bottom + i];
- argv[bottom + i] =
- argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- SWAP_FLAGS(bottom + i,
- top - (middle - bottom) + i);
- }
- /* Exclude the moved bottom segment from further
- * swapping. */
- top -= len;
- } else {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment.
- */
- for (i = 0; i < len; i++) {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- SWAP_FLAGS(bottom + i, middle + i);
- }
- /* Exclude the moved top segment from further swapping.
- */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-#if defined __STDC__ && __STDC__
-static const char *_getopt_initialize(int, char *const *, const char *);
-#endif
-static const char *_getopt_initialize(argc, argv, optstring) int argc;
-char *const *argv;
-const char *optstring;
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- first_nonopt = last_nonopt = optind;
-
- nextchar = NULL;
-
- posixly_correct = getenv("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-') {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- } else if (optstring[0] == '+') {
- ordering = REQUIRE_ORDER;
- ++optstring;
- } else if (posixly_correct != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
-
-#ifdef _LIBC
- if (posixly_correct == NULL && argc == original_argc
- && argv == original_argv) {
- if (nonoption_flags_max_len == 0) {
- if (__getopt_nonoption_flags == NULL
- || __getopt_nonoption_flags[0] == '\0')
- nonoption_flags_max_len = -1;
- else {
- const char *orig_str = __getopt_nonoption_flags;
- int len = nonoption_flags_max_len =
- strlen(orig_str);
- if (nonoption_flags_max_len < argc)
- nonoption_flags_max_len = argc;
- __getopt_nonoption_flags =
- (char *)malloc(nonoption_flags_max_len);
- if (__getopt_nonoption_flags == NULL)
- nonoption_flags_max_len = -1;
- else
- memset(__mempcpy(
- __getopt_nonoption_flags,
- orig_str, len),
- '\0',
- nonoption_flags_max_len - len);
- }
- }
- nonoption_flags_len = nonoption_flags_max_len;
- } else
- nonoption_flags_len = 0;
-#endif
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns -1.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int _getopt_internal(argc, argv, optstring, longopts, longind,
- long_only) int argc;
-char *const *argv;
-const char *optstring;
-const struct option *longopts;
-int *longind;
-int long_only;
-{
- optarg = NULL;
-
- if (optind == 0 || !__getopt_initialized) {
- if (optind == 0)
- optind = 1; /* Don't scan ARGV[0], the program name. */
- optstring = _getopt_initialize(argc, argv, optstring);
- __getopt_initialized = 1;
- }
-
-/* Test whether ARGV[optind] points to a non-option argument.
- Either it does not have option syntax, or there is an environment flag
- from the shell indicating it is not an option. The later information
- is only used when the used in the GNU libc. */
-#ifdef _LIBC
-#define NONOPTION_P \
- (argv[optind][0] != '-' || argv[optind][1] == '\0' \
- || (optind < nonoption_flags_len \
- && __getopt_nonoption_flags[optind] == '1'))
-#else
-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#endif
-
- if (nextchar == NULL || *nextchar == '\0') {
- /* Advance to the next ARGV-element. */
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has
- been
- moved back by the user (who may also have changed the
- arguments). */
- if (last_nonopt > optind)
- last_nonopt = optind;
- if (first_nonopt > optind)
- first_nonopt = optind;
-
- if (ordering == PERMUTE) {
- /* If we have just processed some options following some
- non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt
- && last_nonopt != optind)
- exchange((char **)argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously
- skipped. */
-
- while (optind < argc && NONOPTION_P)
- optind++;
- last_nonopt = optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an
- option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp(argv[optind], "--")) {
- optind++;
-
- if (first_nonopt != last_nonopt
- && last_nonopt != optind)
- exchange((char **)argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted.
- */
-
- if (optind == argc) {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest
- them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return -1;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it
- by. */
-
- if (NONOPTION_P) {
- if (ordering == REQUIRE_ORDER)
- return -1;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- nextchar = (argv[optind] + 1
- + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[optind][1] == '-'
- || (long_only && (argv[optind][2]
- || !my_index(optstring, argv[optind][1]))))) {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = -1;
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name;
- p++, option_index++)
- if (!strncmp(p->name, nextchar, nameend - nextchar)) {
- if ((unsigned int)(nameend - nextchar)
- == (unsigned int)strlen(p->name)) {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- } else if (pfound == NULL) {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- } else
- /* Second or later nonexact match found.
- */
- ambig = 1;
- }
-
- if (ambig && !exact) {
- if (opterr)
- fprintf(stderr,
- _("%s: option `%s' is ambiguous\n"),
- argv[0], argv[optind]);
- nextchar += strlen(nextchar);
- optind++;
- optopt = 0;
- return '?';
- }
-
- if (pfound != NULL) {
- option_index = indfound;
- optind++;
- if (*nameend) {
- /* Don't test has_arg with >, because some C
- compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else {
- if (opterr) {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf(stderr,
- _("%s: option `--%s' doesn't allow an argument\n"),
- argv[0],
- pfound->name);
- else
- /* +option or -option */
- fprintf(stderr,
- _("%s: option `%c%s' doesn't allow an argument\n"),
- argv[0],
- argv[optind - 1]
- [0],
- pfound->name);
- }
-
- nextchar += strlen(nextchar);
-
- optopt = pfound->val;
- return '?';
- }
- } else if (pfound->has_arg == 1) {
- if (optind < argc)
- optarg = argv[optind++];
- else {
- if (opterr)
- fprintf(stderr,
- _("%s: option `%s' requires an argument\n"),
- argv[0],
- argv[optind - 1]);
- nextchar += strlen(nextchar);
- optopt = pfound->val;
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen(nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag) {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not
- getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-'
- || my_index(optstring, *nextchar) == NULL) {
- if (opterr) {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf(stderr,
- _("%s: unrecognized option `--%s'\n"),
- argv[0], nextchar);
- else
- /* +option or -option */
- fprintf(stderr,
- _("%s: unrecognized option `%c%s'\n"),
- argv[0], argv[optind][0],
- nextchar);
- }
- nextchar = (char *)"";
- optind++;
- optopt = 0;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index(optstring, c);
-
- /* Increment `optind' when we start to process its last
- * character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':') {
- if (opterr) {
- if (posixly_correct)
- /* 1003.2 specifies the format of this
- * message. */
- fprintf(stderr,
- _("%s: illegal option -- %c\n"),
- argv[0], c);
- else
- fprintf(stderr,
- _("%s: invalid option -- %c\n"),
- argv[0], c);
- }
- optopt = c;
- return '?';
- }
- /* Convenience. Treat POSIX -W foo same as long option --foo */
- if (temp[0] == 'W' && temp[1] == ';') {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = 0;
- int option_index;
-
- /* This is an option that requires an argument. */
- if (*nextchar != '\0') {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the
- rest as an arg,
- we must advance to the next element now. */
- optind++;
- } else if (optind == argc) {
- if (opterr) {
- /* 1003.2 specifies the format of this
- * message. */
- fprintf(stderr,
- _("%s: option requires an argument -- %c\n"),
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- return c;
- } else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt
- as argument. */
- optarg = argv[optind++];
-
- /* optarg is now the argument, see if it's in the
- table of longopts. */
-
- for (nextchar = nameend = optarg;
- *nameend && *nameend != '='; nameend++)
- /* Do nothing. */;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name;
- p++, option_index++)
- if (!strncmp(p->name, nextchar,
- nameend - nextchar)) {
- if ((unsigned int)(nameend - nextchar)
- == strlen(p->name)) {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- } else if (pfound == NULL) {
- /* First nonexact match found.
- */
- pfound = p;
- indfound = option_index;
- } else
- /* Second or later nonexact
- * match found. */
- ambig = 1;
- }
- if (ambig && !exact) {
- if (opterr)
- fprintf(stderr,
- _("%s: option `-W %s' is ambiguous\n"),
- argv[0], argv[optind]);
- nextchar += strlen(nextchar);
- optind++;
- return '?';
- }
- if (pfound != NULL) {
- option_index = indfound;
- if (*nameend) {
- /* Don't test has_arg with >, because
- some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else {
- if (opterr)
- fprintf(stderr, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
- argv[0],
- pfound->name);
-
- nextchar += strlen(nextchar);
- return '?';
- }
- } else if (pfound->has_arg == 1) {
- if (optind < argc)
- optarg = argv[optind++];
- else {
- if (opterr)
- fprintf(stderr,
- _("%s: option `%s' requires an argument\n"),
- argv[0],
- argv[optind
- - 1]);
- nextchar += strlen(nextchar);
- return optstring[0] == ':'
- ? ':'
- : '?';
- }
- }
- nextchar += strlen(nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag) {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- nextchar = NULL;
- return 'W'; /* Let the application handle it. */
- }
- if (temp[1] == ':') {
- if (temp[2] == ':') {
- /* This is an option that accepts an argument
- * optionally. */
- if (*nextchar != '\0') {
- optarg = nextchar;
- optind++;
- } else
- optarg = NULL;
- nextchar = NULL;
- } else {
- /* This is an option that requires an argument.
- */
- if (*nextchar != '\0') {
- optarg = nextchar;
- /* If we end this ARGV-element by taking
- the rest as an arg,
- we must advance to the next element
- now. */
- optind++;
- } else if (optind == argc) {
- if (opterr) {
- /* 1003.2 specifies the format
- * of this message. */
- fprintf(stderr,
- _("%s: option requires an argument -- %c\n"),
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- } else
- /* We already incremented `optind' once;
- increment it again when taking next
- ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-#ifdef REALLY_NEED_PLAIN_GETOPT
-
-int getopt(argc, argv, optstring) int argc;
-char *const *argv;
-const char *optstring;
-{
- return _getopt_internal(argc, argv, optstring, (const struct option *)0,
- (int *)0, 0);
-}
-
-#endif /* REALLY_NEED_PLAIN_GETOPT */
-
-#endif /* Not ELIDE_CODE. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int main(argc, argv) int argc;
-char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1) {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt(argc, argv, "abc:d:0123456789");
- if (c == -1)
- break;
-
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0
- && digit_optind != this_option_optind)
- printf("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf("option %c\n", c);
- break;
-
- case 'a':
- printf("option a\n");
- break;
-
- case 'b':
- printf("option b\n");
- break;
-
- case 'c':
- printf("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc) {
- printf("non-option ARGV-elements: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
- }
-
- exit(0);
-}
-
-#endif /* TEST */
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* Declarations for getopt.
- * Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
- *
- * NOTE: The canonical source of this file is maintained with the GNU C Library.
- * Bugs can be reported to bug-glibc@gnu.org.
- */
-
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
-
-/*
- * The operating system may or may not provide getopt_long(), and if
- * so it may or may not be a version we are willing to use. Our
- * strategy is to declare getopt here, and then provide code unless
- * the supplied version is adequate. The difficult case is when a
- * declaration for getopt is provided, as our declaration must match.
- *
- * XXX Arguably this version should be named differently, and the
- * local names defined to refer to the system version when we choose
- * to use the system version.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option {
-#if defined(__STDC__) && __STDC__
- const char *name;
-#else
- char *name;
-#endif
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-
-#if defined(__STDC__) && __STDC__
-
-#ifdef REALLY_NEED_PLAIN_GETOPT
-
-/*
- * getopt is defined in POSIX.2. Assume that if the system defines
- * getopt that it complies with POSIX.2. If not, an autoconf test
- * should be written to define NONPOSIX_GETOPT_DEFINITION.
- */
-#ifndef NONPOSIX_GETOPT_DEFINITION
-extern int getopt(int argc, char *const *argv, const char *shortopts);
-#else /* NONPOSIX_GETOPT_DEFINITION */
-extern int getopt(void);
-#endif /* NONPOSIX_GETOPT_DEFINITION */
-
-#endif
-
-
-extern int getopt_long(int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind);
-extern int getopt_long_only(int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind);
-
-/* Internal only. Users should not call this directly. */
-extern int _getopt_internal(int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind,
- int long_only);
-#else /* not __STDC__ */
-
-#ifdef REALLY_NEED_PLAIN_GETOPT
-extern int getopt();
-#endif /* REALLY_NEED_PLAIN_GETOPT */
-
-extern int getopt_long();
-extern int getopt_long_only();
-
-extern int _getopt_internal();
-
-#endif /* __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* getopt.h */
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- * Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
- * Free Software Foundation, Inc.
- *
- * NOTE: The canonical source of this file is maintained with the GNU C Library.
- * Bugs can be reported to bug-glibc@gnu.org.
- */
-
-#include <zebra.h>
-#include "getopt.h"
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int getopt_long(argc, argv, options, long_options, opt_index) int argc;
-char *const *argv;
-const char *options;
-const struct option *long_options;
-int *opt_index;
-{
- return _getopt_internal(argc, argv, options, long_options, opt_index,
- 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int getopt_long_only(argc, argv, options, long_options, opt_index) int argc;
-char *const *argv;
-const char *options;
-const struct option *long_options;
-int *opt_index;
-{
- return _getopt_internal(argc, argv, options, long_options, opt_index,
- 1);
-}
-
-
-#endif /* Not ELIDE_CODE. */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int main(argc, argv) int argc;
-char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1) {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] = {
- {"add", 1, 0, 0}, {"append", 0, 0, 0},
- {"delete", 1, 0, 0}, {"verbose", 0, 0, 0},
- {"create", 0, 0, 0}, {"file", 1, 0, 0},
- {0, 0, 0, 0}};
-
- c = getopt_long(argc, argv, "abc:d:0123456789", long_options,
- &option_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 0:
- printf("option %s", long_options[option_index].name);
- if (optarg)
- printf(" with arg %s", optarg);
- printf("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0
- && digit_optind != this_option_optind)
- printf("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf("option %c\n", c);
- break;
-
- case 'a':
- printf("option a\n");
- break;
-
- case 'b':
- printf("option b\n");
- break;
-
- case 'c':
- printf("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc) {
- printf("non-option ARGV-elements: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
- }
-
- exit(0);
-}
-
-#endif /* TEST */
exit(0);
}
-struct thread_master *master;
+struct event_loop *master;
int main(int argc, char **argv)
{
- struct thread thread;
+ struct event event;
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
zlog_aux_init("NONE: ", LOG_DEBUG);
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ while (event_fetch(master, &event))
+ event_call(&event);
/* Not reached. */
exit(0);
hash->stats.empty = hash->size;
}
+void hash_clean_and_free(struct hash **hash, void (*free_func)(void *))
+{
+ if (!*hash)
+ return;
+
+ hash_clean(*hash, free_func);
+ hash_free(*hash);
+ *hash = NULL;
+}
+
static void hash_to_list_iter(struct hash_bucket *hb, void *arg)
{
struct list *list = arg;
*/
extern void hash_clean(struct hash *hash, void (*free_func)(void *));
+/*
+ * Remove all elements from a hash table and free the table,
+ * setting the pointer to NULL.
+ *
+ * hash
+ * hash table to operate on
+ * free_func
+ * function to call with each removed item, intended to free the data
+ */
+extern void hash_clean_and_free(struct hash **hash, void (*free_func)(void *));
+
/*
* Delete a hash table.
*
void if_rmap_ctx_delete(struct if_rmap_ctx *ctx)
{
listnode_delete(if_rmap_ctx_list, ctx);
- hash_clean(ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
+ hash_clean_and_free(&ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
if (ctx->name)
XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx);
XFREE(MTYPE_IF_RMAP_CTX, ctx);
#include "memory.h"
#include "prefix.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#include "zclient.h"
#include "table.h"
* update state
*/
if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP)
ldp_sync_info->state =
uint8_t enabled; /* enabled */
uint8_t state; /* running state */
uint16_t holddown; /* timer value */
- struct thread *t_holddown; /* holddown timer*/
+ struct event *t_holddown; /* holddown timer*/
uint32_t metric[2]; /* isis interface metric */
};
#include "frrscript.h"
#include "systemd.h"
-DEFINE_HOOK(frr_early_init, (struct thread_master * tm), (tm));
-DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
-DEFINE_HOOK(frr_config_pre, (struct thread_master * tm), (tm));
-DEFINE_HOOK(frr_config_post, (struct thread_master * tm), (tm));
+DEFINE_HOOK(frr_early_init, (struct event_loop * tm), (tm));
+DEFINE_HOOK(frr_late_init, (struct event_loop * tm), (tm));
+DEFINE_HOOK(frr_config_pre, (struct event_loop * tm), (tm));
+DEFINE_HOOK(frr_config_post, (struct event_loop * tm), (tm));
DEFINE_KOOH(frr_early_fini, (), ());
DEFINE_KOOH(frr_fini, (), ());
fprintf(stderr, "%s: %s\n", prefix, errstr);
}
-static struct thread_master *master;
-struct thread_master *frr_init(void)
+static struct event_loop *master;
+struct event_loop *frr_init(void)
{
struct option_chain *oc;
struct log_arg *log_arg;
zprivs_init(di->privs);
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
signal_init(master, di->n_signals, di->signals);
hook_call(frr_early_init, master);
* to read the config in after thread execution starts, so that
* we can match this behavior.
*/
-static void frr_config_read_in(struct thread *t)
+static void frr_config_read_in(struct event *t)
{
hook_call(frr_config_pre, master);
exit(0);
}
- thread_add_event(master, frr_config_read_in, NULL, 0,
- &di->read_in);
+ event_add_event(master, frr_config_read_in, NULL, 0,
+ &di->read_in);
}
if (di->daemon_mode || di->terminal)
}
}
-static struct thread *daemon_ctl_thread = NULL;
+static struct event *daemon_ctl_thread = NULL;
-static void frr_daemon_ctl(struct thread *t)
+static void frr_daemon_ctl(struct event *t)
{
char buf[1];
ssize_t nr;
}
out:
- thread_add_read(master, frr_daemon_ctl, NULL, daemon_ctl_sock,
- &daemon_ctl_thread);
+ event_add_read(master, frr_daemon_ctl, NULL, daemon_ctl_sock,
+ &daemon_ctl_thread);
}
void frr_detach(void)
frr_check_detach();
}
-void frr_run(struct thread_master *master)
+void frr_run(struct event_loop *master)
{
char instanceinfo[64] = "";
vty_stdio(frr_terminal_close);
if (daemon_ctl_sock != -1) {
set_nonblocking(daemon_ctl_sock);
- thread_add_read(master, frr_daemon_ctl, NULL,
- daemon_ctl_sock, &daemon_ctl_thread);
+ event_add_read(master, frr_daemon_ctl, NULL,
+ daemon_ctl_sock, &daemon_ctl_thread);
}
} else if (di->daemon_mode) {
int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
/* end fixed stderr startup logging */
zlog_startup_end();
- struct thread thread;
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ struct event thread;
+ while (event_fetch(master, &thread))
+ event_call(&thread);
}
void frr_early_fini(void)
frr_pthread_finish();
zprivs_terminate(di->privs);
/* signal_init -> nothing needed */
- thread_master_free(master);
+ event_master_free(master);
master = NULL;
zlog_tls_buffer_fini();
zlog_fini();
#include "typesafe.h"
#include "sigevent.h"
#include "privs.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "getopt.h"
#include "module.h"
bool terminal;
enum frr_cli_mode cli_mode;
- struct thread *read_in;
+ struct event *read_in;
const char *config_file;
const char *backup_config_file;
const char *pid_file;
extern __attribute__((__noreturn__)) void frr_help_exit(int status);
-extern struct thread_master *frr_init(void);
+extern struct event_loop *frr_init(void);
extern const char *frr_get_progname(void);
extern enum frr_cli_mode frr_get_cli_mode(void);
extern uint32_t frr_get_fd_limit(void);
extern bool frr_is_startup_fd(int fd);
/* call order of these hooks is as ordered here */
-DECLARE_HOOK(frr_early_init, (struct thread_master * tm), (tm));
-DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
+DECLARE_HOOK(frr_early_init, (struct event_loop * tm), (tm));
+DECLARE_HOOK(frr_late_init, (struct event_loop * tm), (tm));
/* fork() happens between late_init and config_pre */
-DECLARE_HOOK(frr_config_pre, (struct thread_master * tm), (tm));
-DECLARE_HOOK(frr_config_post, (struct thread_master * tm), (tm));
+DECLARE_HOOK(frr_config_pre, (struct event_loop * tm), (tm));
+DECLARE_HOOK(frr_config_post, (struct event_loop * tm), (tm));
extern void frr_config_fork(void);
-extern void frr_run(struct thread_master *master);
+extern void frr_run(struct event_loop *master);
extern void frr_detach(void);
extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len,
#include <lttng/tracepoint.h>
#include "hash.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "table.h"
TRACEPOINT_LOGLEVEL(frr_libfrr, hash_release, TRACE_INFO)
#define THREAD_SCHEDULE_ARGS \
- TP_ARGS(struct thread_master *, master, const char *, funcname, \
- const char *, schedfrom, int, fromln, struct thread **, \
+ TP_ARGS(struct event_loop *, master, const char *, funcname, \
+ const char *, schedfrom, int, fromln, struct event **, \
thread_ptr, int, fd, int, val, void *, arg, long, time)
TRACEPOINT_EVENT_CLASS(
THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_event)
THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_read)
THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_write)
-THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel)
-THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel_async)
-THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_call)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(event_cancel)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(event_cancel_async)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(event_call)
TRACEPOINT_EVENT(
frr_libfrr,
fb.pos = buf;
- struct thread *tc;
+ struct event *tc;
tc = pthread_getspecific(thread_current);
if (!tc)
void zlog_thread_info(int log_level)
{
- struct thread *tc;
+ struct event *tc;
tc = pthread_getspecific(thread_current);
if (tc)
struct mgmt_be_client_ctx {
int conn_fd;
- struct thread_master *tm;
- struct thread *conn_retry_tmr;
- struct thread *conn_read_ev;
- struct thread *conn_write_ev;
- struct thread *conn_writes_on;
- struct thread *msg_proc_ev;
+ struct event_loop *tm;
+ struct event *conn_retry_tmr;
+ struct event *conn_read_ev;
+ struct event *conn_write_ev;
+ struct event *conn_writes_on;
+ struct event *msg_proc_ev;
uint32_t flags;
struct mgmt_msg_state mstate;
mgmtd__be_message__free_unpacked(be_msg, NULL);
}
-static void mgmt_be_client_proc_msgbufs(struct thread *thread)
+static void mgmt_be_client_proc_msgbufs(struct event *thread)
{
- struct mgmt_be_client_ctx *client_ctx = THREAD_ARG(thread);
+ struct mgmt_be_client_ctx *client_ctx = EVENT_ARG(thread);
if (mgmt_msg_procbufs(&client_ctx->mstate, mgmt_be_client_process_msg,
client_ctx, mgmt_debug_be_client))
mgmt_be_client_register_event(client_ctx, MGMTD_BE_PROC_MSG);
}
-static void mgmt_be_client_read(struct thread *thread)
+static void mgmt_be_client_read(struct event *thread)
{
- struct mgmt_be_client_ctx *client_ctx = THREAD_ARG(thread);
+ struct mgmt_be_client_ctx *client_ctx = EVENT_ARG(thread);
enum mgmt_msg_rsched rv;
rv = mgmt_msg_read(&client_ctx->mstate, client_ctx->conn_fd,
return rv;
}
-static void mgmt_be_client_write(struct thread *thread)
+static void mgmt_be_client_write(struct event *thread)
{
- struct mgmt_be_client_ctx *client_ctx = THREAD_ARG(thread);
+ struct mgmt_be_client_ctx *client_ctx = EVENT_ARG(thread);
enum mgmt_msg_wsched rv;
rv = mgmt_msg_write(&client_ctx->mstate, client_ctx->conn_fd,
assert(rv == MSW_SCHED_NONE);
}
-static void mgmt_be_client_resume_writes(struct thread *thread)
+static void mgmt_be_client_resume_writes(struct event *thread)
{
struct mgmt_be_client_ctx *client_ctx;
- client_ctx = (struct mgmt_be_client_ctx *)THREAD_ARG(thread);
+ client_ctx = (struct mgmt_be_client_ctx *)EVENT_ARG(thread);
assert(client_ctx && client_ctx->conn_fd != -1);
mgmt_be_client_writes_on(client_ctx);
client_ctx->client_params.user_data, true);
}
-static void mgmt_be_client_conn_timeout(struct thread *thread)
+static void mgmt_be_client_conn_timeout(struct event *thread)
{
- mgmt_be_server_connect(THREAD_ARG(thread));
+ mgmt_be_server_connect(EVENT_ARG(thread));
}
static void
switch (event) {
case MGMTD_BE_CONN_READ:
- thread_add_read(client_ctx->tm, mgmt_be_client_read,
+ event_add_read(client_ctx->tm, mgmt_be_client_read,
client_ctx, client_ctx->conn_fd,
&client_ctx->conn_read_ev);
- assert(client_ctx->conn_read_ev);
break;
case MGMTD_BE_CONN_WRITE:
- thread_add_write(client_ctx->tm, mgmt_be_client_write,
+ event_add_write(client_ctx->tm, mgmt_be_client_write,
client_ctx, client_ctx->conn_fd,
&client_ctx->conn_write_ev);
- assert(client_ctx->conn_write_ev);
break;
case MGMTD_BE_PROC_MSG:
tv.tv_usec = MGMTD_BE_MSG_PROC_DELAY_USEC;
- thread_add_timer_tv(client_ctx->tm, mgmt_be_client_proc_msgbufs,
+ event_add_timer_tv(client_ctx->tm, mgmt_be_client_proc_msgbufs,
client_ctx, &tv, &client_ctx->msg_proc_ev);
- assert(client_ctx->msg_proc_ev);
break;
case MGMTD_BE_CONN_WRITES_ON:
- thread_add_timer_msec(client_ctx->tm,
+ event_add_timer_msec(client_ctx->tm,
mgmt_be_client_resume_writes, client_ctx,
MGMTD_BE_MSG_WRITE_DELAY_MSEC,
&client_ctx->conn_writes_on);
- assert(client_ctx->conn_writes_on);
break;
case MGMTD_BE_SERVER:
case MGMTD_BE_CONN_INIT:
MGMTD_BE_CLIENT_DBG(
"Scheduling MGMTD Backend server connection retry after %lu seconds",
intvl_secs);
- thread_add_timer(client_ctx->tm, mgmt_be_client_conn_timeout,
+ event_add_timer(client_ctx->tm, mgmt_be_client_conn_timeout,
(void *)client_ctx, intvl_secs,
&client_ctx->conn_retry_tmr);
}
* Initialize library and try connecting with MGMTD.
*/
uintptr_t mgmt_be_client_lib_init(struct mgmt_be_client_params *params,
- struct thread_master *master_thread)
+ struct event_loop *master_thread)
{
assert(master_thread && params && strlen(params->name)
&& !mgmt_be_client_ctx.tm);
mgmt_msg_destroy(&client_ctx->mstate);
- THREAD_OFF(client_ctx->conn_retry_tmr);
- THREAD_OFF(client_ctx->conn_read_ev);
- THREAD_OFF(client_ctx->conn_write_ev);
- THREAD_OFF(client_ctx->conn_writes_on);
- THREAD_OFF(client_ctx->msg_proc_ev);
+ EVENT_OFF(client_ctx->conn_retry_tmr);
+ EVENT_OFF(client_ctx->conn_read_ev);
+ EVENT_OFF(client_ctx->conn_write_ev);
+ EVENT_OFF(client_ctx->conn_writes_on);
+ EVENT_OFF(client_ctx->msg_proc_ev);
mgmt_be_cleanup_all_txns(client_ctx);
mgmt_be_txns_fini(&client_ctx->txn_head);
}
* Returns:
* Backend client lib handler (nothing but address of mgmt_be_client_ctx)
*/
-extern uintptr_t
-mgmt_be_client_lib_init(struct mgmt_be_client_params *params,
- struct thread_master *master_thread);
+extern uintptr_t mgmt_be_client_lib_init(struct mgmt_be_client_params *params,
+ struct event_loop *master_thread);
/*
* Subscribe with MGMTD for one or more YANG subtree(s).
struct mgmt_fe_client_ctx {
int conn_fd;
- struct thread_master *tm;
- struct thread *conn_retry_tmr;
- struct thread *conn_read_ev;
- struct thread *conn_write_ev;
- struct thread *conn_writes_on;
- struct thread *msg_proc_ev;
+ struct event_loop *tm;
+ struct event *conn_retry_tmr;
+ struct event *conn_read_ev;
+ struct event *conn_write_ev;
+ struct event *conn_writes_on;
+ struct event *msg_proc_ev;
uint32_t flags;
struct mgmt_msg_state mstate;
return rv;
}
-static void mgmt_fe_client_write(struct thread *thread)
+static void mgmt_fe_client_write(struct event *thread)
{
struct mgmt_fe_client_ctx *client_ctx;
enum mgmt_msg_wsched rv;
- client_ctx = (struct mgmt_fe_client_ctx *)THREAD_ARG(thread);
+ client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
rv = mgmt_msg_write(&client_ctx->mstate, client_ctx->conn_fd,
mgmt_debug_fe_client);
if (rv == MSW_SCHED_STREAM)
assert(rv == MSW_SCHED_NONE);
}
-static void mgmt_fe_client_resume_writes(struct thread *thread)
+static void mgmt_fe_client_resume_writes(struct event *thread)
{
struct mgmt_fe_client_ctx *client_ctx;
- client_ctx = (struct mgmt_fe_client_ctx *)THREAD_ARG(thread);
+ client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
assert(client_ctx && client_ctx->conn_fd != -1);
mgmt_fe_client_writes_on(client_ctx);
mgmtd__fe_message__free_unpacked(fe_msg, NULL);
}
-static void mgmt_fe_client_proc_msgbufs(struct thread *thread)
+static void mgmt_fe_client_proc_msgbufs(struct event *thread)
{
struct mgmt_fe_client_ctx *client_ctx;
- client_ctx = (struct mgmt_fe_client_ctx *)THREAD_ARG(thread);
+ client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
if (mgmt_msg_procbufs(&client_ctx->mstate, mgmt_fe_client_process_msg,
client_ctx, mgmt_debug_fe_client))
mgmt_fe_client_register_event(client_ctx, MGMTD_FE_PROC_MSG);
}
-static void mgmt_fe_client_read(struct thread *thread)
+static void mgmt_fe_client_read(struct event *thread)
{
struct mgmt_fe_client_ctx *client_ctx;
enum mgmt_msg_rsched rv;
- client_ctx = (struct mgmt_fe_client_ctx *)THREAD_ARG(thread);
+ client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
rv = mgmt_msg_read(&client_ctx->mstate, client_ctx->conn_fd,
mgmt_debug_fe_client);
}
-static void mgmt_fe_client_conn_timeout(struct thread *thread)
+static void mgmt_fe_client_conn_timeout(struct event *thread)
{
- mgmt_fe_server_connect(THREAD_ARG(thread));
+ mgmt_fe_server_connect(EVENT_ARG(thread));
}
static void
switch (event) {
case MGMTD_FE_CONN_READ:
- thread_add_read(client_ctx->tm, mgmt_fe_client_read,
+ event_add_read(client_ctx->tm, mgmt_fe_client_read,
client_ctx, client_ctx->conn_fd,
&client_ctx->conn_read_ev);
- assert(client_ctx->conn_read_ev);
break;
case MGMTD_FE_CONN_WRITE:
- thread_add_write(client_ctx->tm, mgmt_fe_client_write,
+ event_add_write(client_ctx->tm, mgmt_fe_client_write,
client_ctx, client_ctx->conn_fd,
&client_ctx->conn_write_ev);
- assert(client_ctx->conn_write_ev);
break;
case MGMTD_FE_PROC_MSG:
tv.tv_usec = MGMTD_FE_MSG_PROC_DELAY_USEC;
- thread_add_timer_tv(client_ctx->tm,
+ event_add_timer_tv(client_ctx->tm,
mgmt_fe_client_proc_msgbufs, client_ctx,
&tv, &client_ctx->msg_proc_ev);
- assert(client_ctx->msg_proc_ev);
break;
case MGMTD_FE_CONN_WRITES_ON:
- thread_add_timer_msec(
+ event_add_timer_msec(
client_ctx->tm, mgmt_fe_client_resume_writes,
client_ctx, MGMTD_FE_MSG_WRITE_DELAY_MSEC,
&client_ctx->conn_writes_on);
- assert(client_ctx->conn_writes_on);
break;
case MGMTD_FE_SERVER:
assert(!"mgmt_fe_client_ctx_post_event called incorrectly");
MGMTD_FE_CLIENT_DBG(
"Scheduling MGMTD Frontend server connection retry after %lu seconds",
intvl_secs);
- thread_add_timer(client_ctx->tm, mgmt_fe_client_conn_timeout,
+ event_add_timer(client_ctx->tm, mgmt_fe_client_conn_timeout,
(void *)client_ctx, intvl_secs,
&client_ctx->conn_retry_tmr);
}
* Initialize library and try connecting with MGMTD.
*/
uintptr_t mgmt_fe_client_lib_init(struct mgmt_fe_client_params *params,
- struct thread_master *master_thread)
+ struct event_loop *master_thread)
{
assert(master_thread && params && strlen(params->name)
&& !mgmt_fe_client_ctx.tm);
mgmt_fe_destroy_client_sessions(lib_hndl);
- THREAD_OFF(client_ctx->conn_retry_tmr);
- THREAD_OFF(client_ctx->conn_read_ev);
- THREAD_OFF(client_ctx->conn_write_ev);
- THREAD_OFF(client_ctx->conn_writes_on);
- THREAD_OFF(client_ctx->msg_proc_ev);
+ EVENT_OFF(client_ctx->conn_retry_tmr);
+ EVENT_OFF(client_ctx->conn_read_ev);
+ EVENT_OFF(client_ctx->conn_write_ev);
+ EVENT_OFF(client_ctx->conn_writes_on);
+ EVENT_OFF(client_ctx->msg_proc_ev);
mgmt_msg_destroy(&client_ctx->mstate);
}
#endif
#include "mgmt_pb.h"
-#include "thread.h"
+#include "frrevent.h"
#include "mgmtd/mgmt_defines.h"
/***************************************************************
* Returns:
* Frontend client lib handler (nothing but address of mgmt_fe_client_ctx)
*/
-extern uintptr_t
-mgmt_fe_client_lib_init(struct mgmt_fe_client_params *params,
- struct thread_master *master_thread);
+extern uintptr_t mgmt_fe_client_lib_init(struct mgmt_fe_client_params *params,
+ struct event_loop *master_thread);
/*
* Create a new Session for a Frontend Client connection.
#include "network.h"
#include "sockopt.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "mgmt_msg.h"
#define _MGMT_MSG_H
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#define MGMT_MSG_MARKER (0x4D724B21u) /* ASCII - "MrK!"*/
}
-void nb_init(struct thread_master *tm,
+void nb_init(struct event_loop *tm,
const struct frr_yang_module_info *const modules[],
size_t nmodules, bool db_enabled)
{
nb_nodes_delete();
/* Delete the running configuration. */
- hash_clean(running_config_entries, running_config_entry_free);
- hash_free(running_config_entries);
+ hash_clean_and_free(&running_config_entries, running_config_entry_free);
nb_config_free(running_config);
pthread_mutex_destroy(&running_config_mgmt_lock.mtx);
}
#ifndef _FRR_NORTHBOUND_H_
#define _FRR_NORTHBOUND_H_
-#include "thread.h"
+#include "frrevent.h"
#include "hook.h"
#include "linklist.h"
#include "openbsd-tree.h"
* db_enabled
* Set this to record the transactions in the transaction log.
*/
-extern void nb_init(struct thread_master *tm,
+extern void nb_init(struct event_loop *tm,
const struct frr_yang_module_info *const modules[],
size_t nmodules, bool db_enabled);
struct debug nb_dbg_libyang = {0, "libyang debugging"};
struct nb_config *vty_shared_candidate_config;
-static struct thread_master *master;
+static struct event_loop *master;
static void vty_show_nb_errors(struct vty *vty, int error, const char *errmsg)
{
void nb_cli_confirmed_commit_clean(struct vty *vty)
{
- thread_cancel(&vty->t_confirmed_commit_timeout);
+ event_cancel(&vty->t_confirmed_commit_timeout);
nb_config_free(vty->confirmed_commit_rollback);
vty->confirmed_commit_rollback = NULL;
}
return ret;
}
-static void nb_cli_confirmed_commit_timeout(struct thread *thread)
+static void nb_cli_confirmed_commit_timeout(struct event *thread)
{
- struct vty *vty = THREAD_ARG(thread);
+ struct vty *vty = EVENT_ARG(thread);
/* XXX: broadcast this message to all logged-in users? */
vty_out(vty,
"%% Resetting confirmed-commit timeout to %u minute(s)\n\n",
confirmed_timeout);
- thread_cancel(&vty->t_confirmed_commit_timeout);
- thread_add_timer(master,
- nb_cli_confirmed_commit_timeout, vty,
- confirmed_timeout * 60,
- &vty->t_confirmed_commit_timeout);
+ event_cancel(&vty->t_confirmed_commit_timeout);
+ event_add_timer(master, nb_cli_confirmed_commit_timeout,
+ vty, confirmed_timeout * 60,
+ &vty->t_confirmed_commit_timeout);
} else {
/* Accept commit confirmation. */
vty_out(vty, "%% Commit complete.\n\n");
vty->confirmed_commit_rollback = nb_config_dup(running_config);
vty->t_confirmed_commit_timeout = NULL;
- thread_add_timer(master, nb_cli_confirmed_commit_timeout, vty,
- confirmed_timeout * 60,
- &vty->t_confirmed_commit_timeout);
+ event_add_timer(master, nb_cli_confirmed_commit_timeout, vty,
+ confirmed_timeout * 60,
+ &vty->t_confirmed_commit_timeout);
}
context.client = NB_CLIENT_CLI;
.completions = yang_translator_autocomplete},
{.completions = NULL}};
-void nb_cli_init(struct thread_master *tm)
+void nb_cli_init(struct event_loop *tm)
{
master = tm;
extern void nb_cli_confirmed_commit_clean(struct vty *vty);
extern int nb_cli_confirmed_commit_rollback(struct vty *vty);
extern void nb_cli_install_default(int node);
-extern void nb_cli_init(struct thread_master *tm);
+extern void nb_cli_init(struct event_loop *tm);
extern void nb_cli_terminate(void);
#ifdef __cplusplus
static struct debug nb_dbg_client_confd = {0, "Northbound client: ConfD"};
-static struct thread_master *master;
+static struct event_loop *master;
static struct sockaddr confd_addr;
static int cdb_sub_sock, dp_ctl_sock, dp_worker_sock;
-static struct thread *t_cdb_sub, *t_dp_ctl, *t_dp_worker;
+static struct event *t_cdb_sub, *t_dp_ctl, *t_dp_worker;
static struct confd_daemon_ctx *dctx;
static struct confd_notification_ctx *live_ctx;
static bool confd_connected;
return 0;
}
-static void frr_confd_cdb_read_cb(struct thread *thread)
+static void frr_confd_cdb_read_cb(struct event *thread)
{
- int fd = THREAD_FD(thread);
+ int fd = EVENT_FD(thread);
enum cdb_sub_notification cdb_ev;
int flags;
int *subp = NULL;
int reslen = 0;
- thread_add_read(master, frr_confd_cdb_read_cb, NULL, fd, &t_cdb_sub);
+ event_add_read(master, frr_confd_cdb_read_cb, NULL, fd, &t_cdb_sub);
if (cdb_read_subscription_socket2(fd, &cdb_ev, &flags, &subp, &reslen)
!= CONFD_OK) {
}
pthread_detach(cdb_trigger_thread);
- thread_add_read(master, frr_confd_cdb_read_cb, NULL, cdb_sub_sock,
- &t_cdb_sub);
+ event_add_read(master, frr_confd_cdb_read_cb, NULL, cdb_sub_sock,
+ &t_cdb_sub);
return 0;
static void frr_confd_finish_cdb(void)
{
if (cdb_sub_sock > 0) {
- THREAD_OFF(t_cdb_sub);
+ EVENT_OFF(t_cdb_sub);
cdb_close(cdb_sub_sock);
}
}
return 0;
}
-static void frr_confd_dp_ctl_read(struct thread *thread)
+static void frr_confd_dp_ctl_read(struct event *thread)
{
- struct confd_daemon_ctx *dctx = THREAD_ARG(thread);
- int fd = THREAD_FD(thread);
+ struct confd_daemon_ctx *dctx = EVENT_ARG(thread);
+ int fd = EVENT_FD(thread);
- thread_add_read(master, frr_confd_dp_ctl_read, dctx, fd, &t_dp_ctl);
+ event_add_read(master, frr_confd_dp_ctl_read, dctx, fd, &t_dp_ctl);
frr_confd_dp_read(dctx, fd);
}
-static void frr_confd_dp_worker_read(struct thread *thread)
+static void frr_confd_dp_worker_read(struct event *thread)
{
- struct confd_daemon_ctx *dctx = THREAD_ARG(thread);
- int fd = THREAD_FD(thread);
+ struct confd_daemon_ctx *dctx = EVENT_ARG(thread);
+ int fd = EVENT_FD(thread);
- thread_add_read(master, frr_confd_dp_worker_read, dctx, fd, &t_dp_worker);
+ event_add_read(master, frr_confd_dp_worker_read, dctx, fd,
+ &t_dp_worker);
frr_confd_dp_read(dctx, fd);
}
goto error;
}
- thread_add_read(master, frr_confd_dp_ctl_read, dctx, dp_ctl_sock,
- &t_dp_ctl);
- thread_add_read(master, frr_confd_dp_worker_read, dctx, dp_worker_sock,
- &t_dp_worker);
+ event_add_read(master, frr_confd_dp_ctl_read, dctx, dp_ctl_sock,
+ &t_dp_ctl);
+ event_add_read(master, frr_confd_dp_worker_read, dctx, dp_worker_sock,
+ &t_dp_worker);
return 0;
static void frr_confd_finish_dp(void)
{
if (dp_worker_sock > 0) {
- THREAD_OFF(t_dp_worker);
+ EVENT_OFF(t_dp_worker);
close(dp_worker_sock);
}
if (dp_ctl_sock > 0) {
- THREAD_OFF(t_dp_ctl);
+ EVENT_OFF(t_dp_ctl);
close(dp_ctl_sock);
}
if (dctx != NULL)
return 0;
}
-static int frr_confd_module_late_init(struct thread_master *tm)
+static int frr_confd_module_late_init(struct event_loop *tm)
{
master = tm;
#include "log.h"
#include "libfrr.h"
#include "lib/version.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "command.h"
#include "lib_errors.h"
#include "northbound.h"
*/
static bool nb_dbg_client_grpc = 0;
-static struct thread_master *main_master;
+static struct event_loop *main_master;
static struct frr_pthread *fpt;
* state will either be MORE or FINISH. It will always be FINISH
* for Unary RPCs.
*/
- thread_add_event(main_master, c_callback, (void *)this, 0,
- NULL);
+ event_add_event(main_master, c_callback, (void *)this, 0, NULL);
pthread_mutex_lock(&this->cmux);
while (this->state == PROCESS)
}
protected:
- virtual CallState run_mainthread(struct thread *thread) = 0;
+ virtual CallState run_mainthread(struct event *thread) = 0;
- static void c_callback(struct thread *thread)
+ static void c_callback(struct event *thread)
{
- auto _tag = static_cast<RpcStateBase *>(THREAD_ARG(thread));
+ auto _tag = static_cast<RpcStateBase *>(EVENT_ARG(thread));
/*
* We hold the lock until the callback finishes and has updated
* _tag->state, then we signal done and release.
©->responder, cq, cq, copy);
}
- CallState run_mainthread(struct thread *thread) override
+ CallState run_mainthread(struct event *thread) override
{
// Unary RPC are always finished, see "Unary" :)
grpc::Status status = this->callback(this);
©->async_responder, cq, cq, copy);
}
- CallState run_mainthread(struct thread *thread) override
+ CallState run_mainthread(struct event *thread) override
{
if (this->callback(this))
return MORE;
* fork. This is done by scheduling this init function as an event task, since
* the event loop doesn't run until after fork.
*/
-static void frr_grpc_module_very_late_init(struct thread *thread)
+static void frr_grpc_module_very_late_init(struct event *thread)
{
const char *args = THIS_MODULE->load_args;
uint port = GRPC_DEFAULT_PORT;
flog_err(EC_LIB_GRPC_INIT, "failed to initialize the gRPC module");
}
-static int frr_grpc_module_late_init(struct thread_master *tm)
+static int frr_grpc_module_late_init(struct event_loop *tm)
{
main_master = tm;
hook_register(frr_fini, frr_grpc_finish);
- thread_add_event(tm, frr_grpc_module_very_late_init, NULL, 0, NULL);
+ event_add_event(tm, frr_grpc_module_very_late_init, NULL, 0, NULL);
return 0;
}
static struct debug nb_dbg_client_sysrepo = {0, "Northbound client: Sysrepo"};
-static struct thread_master *master;
+static struct event_loop *master;
static sr_session_ctx_t *session;
static sr_conn_ctx_t *connection;
static struct nb_transaction *transaction;
-static void frr_sr_read_cb(struct thread *thread);
+static void frr_sr_read_cb(struct event *thread);
static int frr_sr_finish(void);
/* Convert FRR YANG data value to sysrepo YANG data value. */
return NB_OK;
}
-static void frr_sr_read_cb(struct thread *thread)
+static void frr_sr_read_cb(struct event *thread)
{
- struct yang_module *module = THREAD_ARG(thread);
- int fd = THREAD_FD(thread);
+ struct yang_module *module = EVENT_ARG(thread);
+ int fd = EVENT_FD(thread);
int ret;
ret = sr_subscription_process_events(module->sr_subscription, session,
return;
}
- thread_add_read(master, frr_sr_read_cb, module, fd, &module->sr_thread);
+ event_add_read(master, frr_sr_read_cb, module, fd, &module->sr_thread);
}
static void frr_sr_subscribe_config(struct yang_module *module)
sr_strerror(ret));
goto cleanup;
}
- thread_add_read(master, frr_sr_read_cb, module,
- event_pipe, &module->sr_thread);
+ event_add_read(master, frr_sr_read_cb, module, event_pipe,
+ &module->sr_thread);
}
hook_register(nb_notification_send, frr_sr_notification_send);
if (!module->sr_subscription)
continue;
sr_unsubscribe(module->sr_subscription);
- THREAD_OFF(module->sr_thread);
+ EVENT_OFF(module->sr_thread);
}
if (session)
return 0;
}
-static int frr_sr_module_config_loaded(struct thread_master *tm)
+static int frr_sr_module_config_loaded(struct event_loop *tm)
{
master = tm;
return 0;
}
-static int frr_sr_module_late_init(struct thread_master *tm)
+static int frr_sr_module_late_init(struct event_loop *tm)
{
frr_sr_cli_init();
if (IPV4_CLASS_D(ip))
return false;
- if (IPV4_CLASS_E(ip)) {
+ if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_E(ip)) {
if (cmd_allow_reserved_ranges_get())
return true;
else
/* NOTE: This routine expects the address argument in network byte order. */
static inline bool ipv4_martian(const struct in_addr *addr)
{
- in_addr_t ip = ntohl(addr->s_addr);
-
- if (IPV4_NET0(ip) || IPV4_NET127(ip) || !ipv4_unicast_valid(addr)) {
+ if (!ipv4_unicast_valid(addr))
return true;
- }
return false;
}
struct pullwr {
int fd;
- struct thread_master *tm;
+ struct event_loop *tm;
/* writer == NULL <=> we're idle */
- struct thread *writer;
+ struct event *writer;
void *arg;
void (*fill)(void *, struct pullwr *);
DEFINE_MTYPE_STATIC(LIB, PULLWR_HEAD, "pull-driven write controller");
DEFINE_MTYPE_STATIC(LIB, PULLWR_BUF, "pull-driven write buffer");
-static void pullwr_run(struct thread *t);
+static void pullwr_run(struct event *t);
-struct pullwr *_pullwr_new(struct thread_master *tm, int fd,
- void *arg,
- void (*fill)(void *, struct pullwr *),
- void (*err)(void *, struct pullwr *, bool))
+struct pullwr *_pullwr_new(struct event_loop *tm, int fd, void *arg,
+ void (*fill)(void *, struct pullwr *),
+ void (*err)(void *, struct pullwr *, bool))
{
struct pullwr *pullwr;
void pullwr_del(struct pullwr *pullwr)
{
- THREAD_OFF(pullwr->writer);
+ EVENT_OFF(pullwr->writer);
XFREE(MTYPE_PULLWR_BUF, pullwr->buffer);
XFREE(MTYPE_PULLWR_HEAD, pullwr);
if (pullwr->writer)
return;
- thread_add_timer(pullwr->tm, pullwr_run, pullwr, 0, &pullwr->writer);
+ event_add_timer(pullwr->tm, pullwr_run, pullwr, 0, &pullwr->writer);
}
static size_t pullwr_iov(struct pullwr *pullwr, struct iovec *iov)
pullwr_bump(pullwr);
}
-static void pullwr_run(struct thread *t)
+static void pullwr_run(struct event *t)
{
- struct pullwr *pullwr = THREAD_ARG(t);
+ struct pullwr *pullwr = EVENT_ARG(t);
struct iovec iov[2];
size_t niov, lastvalid;
ssize_t nwr;
if (pullwr->valid == 0) {
/* we made a fill() call above that didn't feed any
* data in, and we have nothing more queued, so we go
- * into idle, i.e. no calling thread_add_write()
+ * into idle, i.e. no calling event_add_write()
*/
pullwr_resize(pullwr, 0);
return;
* is full and we go wait until it's available for writing again.
*/
- thread_add_write(pullwr->tm, pullwr_run, pullwr, pullwr->fd,
+ event_add_write(pullwr->tm, pullwr_run, pullwr, pullwr->fd,
&pullwr->writer);
/* if we hit the time limit, just keep the buffer, we'll probably need
#include <stdbool.h>
#include <stdint.h>
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#ifdef __cplusplus
* and released with pullwr_del(). This can be done from inside the callback,
* the pullwr code holds no more references on it when calling err().
*/
-extern struct pullwr *_pullwr_new(struct thread_master *tm, int fd,
- void *arg,
- void (*fill)(void *, struct pullwr *),
- void (*err)(void *, struct pullwr *, bool eof));
+extern struct pullwr *_pullwr_new(struct event_loop *tm, int fd, void *arg,
+ void (*fill)(void *, struct pullwr *),
+ void (*err)(void *, struct pullwr *,
+ bool eof));
extern void pullwr_del(struct pullwr *pullwr);
/* type-checking wrapper. makes sure fill() and err() take a first argument
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "hash.h"
#include "log.h"
#include "typesafe.h"
#include "jhash.h"
-#include "thread.h"
+#include "frrevent.h"
#include "lib_errors.h"
#include "resolver.h"
#include "command.h"
struct resolver_state {
ares_channel channel;
- struct thread_master *master;
- struct thread *timeout;
+ struct event_loop *master;
+ struct event *timeout;
};
static struct resolver_state state;
int fd;
struct resolver_state *state;
- struct thread *t_read, *t_write;
+ struct event *t_read, *t_write;
};
static int resolver_fd_cmp(const struct resolver_fd *a,
static void resolver_update_timeouts(struct resolver_state *r);
-static void resolver_cb_timeout(struct thread *t)
+static void resolver_cb_timeout(struct event *t)
{
- struct resolver_state *r = THREAD_ARG(t);
+ struct resolver_state *r = EVENT_ARG(t);
ares_process(r->channel, NULL, NULL);
resolver_update_timeouts(r);
}
-static void resolver_cb_socket_readable(struct thread *t)
+static void resolver_cb_socket_readable(struct event *t)
{
- struct resolver_fd *resfd = THREAD_ARG(t);
+ struct resolver_fd *resfd = EVENT_ARG(t);
struct resolver_state *r = resfd->state;
- thread_add_read(r->master, resolver_cb_socket_readable, resfd,
- resfd->fd, &resfd->t_read);
+ event_add_read(r->master, resolver_cb_socket_readable, resfd, resfd->fd,
+ &resfd->t_read);
/* ^ ordering important:
- * ares_process_fd may transitively call THREAD_OFF(resfd->t_read)
+ * ares_process_fd may transitively call EVENT_OFF(resfd->t_read)
* combined with resolver_fd_drop_maybe, so resfd may be free'd after!
*/
ares_process_fd(r->channel, resfd->fd, ARES_SOCKET_BAD);
resolver_update_timeouts(r);
}
-static void resolver_cb_socket_writable(struct thread *t)
+static void resolver_cb_socket_writable(struct event *t)
{
- struct resolver_fd *resfd = THREAD_ARG(t);
+ struct resolver_fd *resfd = EVENT_ARG(t);
struct resolver_state *r = resfd->state;
- thread_add_write(r->master, resolver_cb_socket_writable, resfd,
- resfd->fd, &resfd->t_write);
+ event_add_write(r->master, resolver_cb_socket_writable, resfd,
+ resfd->fd, &resfd->t_write);
/* ^ ordering important:
- * ares_process_fd may transitively call THREAD_OFF(resfd->t_write)
+ * ares_process_fd may transitively call EVENT_OFF(resfd->t_write)
* combined with resolver_fd_drop_maybe, so resfd may be free'd after!
*/
ares_process_fd(r->channel, ARES_SOCKET_BAD, resfd->fd);
{
struct timeval *tv, tvbuf;
- THREAD_OFF(r->timeout);
+ EVENT_OFF(r->timeout);
tv = ares_timeout(r->channel, NULL, &tvbuf);
if (tv) {
unsigned int timeoutms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
- thread_add_timer_msec(r->master, resolver_cb_timeout, r,
- timeoutms, &r->timeout);
+ event_add_timer_msec(r->master, resolver_cb_timeout, r,
+ timeoutms, &r->timeout);
}
}
assert(resfd->state == r);
if (!readable)
- THREAD_OFF(resfd->t_read);
+ EVENT_OFF(resfd->t_read);
else if (!resfd->t_read)
- thread_add_read(r->master, resolver_cb_socket_readable, resfd,
- fd, &resfd->t_read);
+ event_add_read(r->master, resolver_cb_socket_readable, resfd,
+ fd, &resfd->t_read);
if (!writable)
- THREAD_OFF(resfd->t_write);
+ EVENT_OFF(resfd->t_write);
else if (!resfd->t_write)
- thread_add_write(r->master, resolver_cb_socket_writable, resfd,
- fd, &resfd->t_write);
+ event_add_write(r->master, resolver_cb_socket_writable, resfd,
+ fd, &resfd->t_write);
resolver_fd_drop_maybe(resfd);
}
callback(query, NULL, i, &addr[0]);
}
-static void resolver_cb_literal(struct thread *t)
+static void resolver_cb_literal(struct event *t)
{
- struct resolver_query *query = THREAD_ARG(t);
+ struct resolver_query *query = EVENT_ARG(t);
void (*callback)(struct resolver_query *, const char *, int,
union sockunion *);
/* for consistency with proper name lookup, don't call the
* callback immediately; defer to thread loop
*/
- thread_add_timer_msec(state.master, resolver_cb_literal,
- query, 0, &query->literal_cb);
+ event_add_timer_msec(state.master, resolver_cb_literal, query,
+ 0, &query->literal_cb);
return;
}
}
-void resolver_init(struct thread_master *tm)
+void resolver_init(struct event_loop *tm)
{
struct ares_options ares_opts;
#ifndef _FRR_RESOLVER_H
#define _FRR_RESOLVER_H
-#include "thread.h"
+#include "frrevent.h"
#include "sockunion.h"
#ifdef __cplusplus
/* used to immediate provide the result if IP literal is passed in */
union sockunion literal_addr;
- struct thread *literal_cb;
+ struct event *literal_cb;
};
-void resolver_init(struct thread_master *tm);
+void resolver_init(struct event_loop *tm);
void resolver_resolve(struct resolver_query *query, int af, vrf_id_t vrf_id,
const char *hostname,
void (*cb)(struct resolver_query *, const char *, int,
/* master signals descriptor struct */
static struct frr_sigevent_master_t {
- struct thread *t;
+ struct event *t;
struct frr_signal_t *signals;
int sigc;
#ifdef SIGEVENT_SCHEDULE_THREAD
/* timer thread to check signals. shouldn't be needed */
-void frr_signal_timer(struct thread *t)
+void frr_signal_timer(struct event *t)
{
struct frr_sigevent_master_t *sigm;
- sigm = THREAD_ARG(t);
+ sigm = EVENT_ARG(t);
sigm->t = NULL;
- thread_add_timer(sigm->t->master, frr_signal_timer, &sigmaster,
- FRR_SIGNAL_TIMER_INTERVAL, &sigm->t);
+ event_add_timer(sigm->t->master, frr_signal_timer, &sigmaster,
+ FRR_SIGNAL_TIMER_INTERVAL, &sigm->t);
frr_sigevent_process();
}
#endif /* SIGEVENT_SCHEDULE_THREAD */
}
}
-void signal_init(struct thread_master *m, int sigc,
- struct frr_signal_t signals[])
+void signal_init(struct event_loop *m, int sigc, struct frr_signal_t signals[])
{
int i = 0;
#ifdef SIGEVENT_SCHEDULE_THREAD
sigmaster.t = NULL;
- thread_add_timer(m, frr_signal_timer, &sigmaster,
- FRR_SIGNAL_TIMER_INTERVAL, &sigmaster.t);
+ event_add_timer(m, frr_signal_timer, &sigmaster,
+ FRR_SIGNAL_TIMER_INTERVAL, &sigmaster.t);
#endif /* SIGEVENT_SCHEDULE_THREAD */
}
#ifndef _FRR_SIGNAL_H
#define _FRR_SIGNAL_H
-#include <thread.h>
+#include <frrevent.h>
#ifdef __cplusplus
extern "C" {
/* initialise sigevent system
* takes:
- * - pointer to valid struct thread_master
+ * - pointer to valid struct event_loop
* - number of elements in passed in signals array
* - array of frr_signal_t's describing signals to handle
* and handlers to use for each signal
*/
-extern void signal_init(struct thread_master *m, int sigc,
+extern void signal_init(struct event_loop *m, int sigc,
struct frr_signal_t *signals);
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/snmp_vars.h>
-#include "thread.h"
+#include "frrevent.h"
#include "hook.h"
#ifdef __cplusplus
*/
extern bool smux_enabled(void);
-extern void smux_init(struct thread_master *tm);
+extern void smux_init(struct event_loop *tm);
extern void smux_agentx_enable(void);
extern void smux_register_mib(const char *, struct variable *, size_t, int,
oid[], size_t);
#include "command.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
DEFINE_MTYPE_STATIC(LIB, SPF_BACKOFF, "SPF backoff");
};
struct spf_backoff {
- struct thread_master *m;
+ struct event_loop *m;
/* Timers as per draft */
long init_delay;
/* State machine */
enum spf_backoff_state state;
- struct thread *t_holddown;
- struct thread *t_timetolearn;
+ struct event *t_holddown;
+ struct event *t_timetolearn;
/* For debugging */
char *name;
return "???";
}
-struct spf_backoff *spf_backoff_new(struct thread_master *m, const char *name,
+struct spf_backoff *spf_backoff_new(struct event_loop *m, const char *name,
long init_delay, long short_delay,
long long_delay, long holddown,
long timetolearn)
if (!backoff)
return;
- thread_cancel(&backoff->t_holddown);
- thread_cancel(&backoff->t_timetolearn);
+ event_cancel(&backoff->t_holddown);
+ event_cancel(&backoff->t_timetolearn);
XFREE(MTYPE_SPF_BACKOFF_NAME, backoff->name);
XFREE(MTYPE_SPF_BACKOFF, backoff);
}
-static void spf_backoff_timetolearn_elapsed(struct thread *thread)
+static void spf_backoff_timetolearn_elapsed(struct event *thread)
{
- struct spf_backoff *backoff = THREAD_ARG(thread);
+ struct spf_backoff *backoff = EVENT_ARG(thread);
backoff->state = SPF_BACKOFF_LONG_WAIT;
backoff_debug("SPF Back-off(%s) TIMETOLEARN elapsed, move to state %s",
backoff->name, spf_backoff_state2str(backoff->state));
}
-static void spf_backoff_holddown_elapsed(struct thread *thread)
+static void spf_backoff_holddown_elapsed(struct event *thread)
{
- struct spf_backoff *backoff = THREAD_ARG(thread);
+ struct spf_backoff *backoff = EVENT_ARG(thread);
- THREAD_OFF(backoff->t_timetolearn);
+ EVENT_OFF(backoff->t_timetolearn);
timerclear(&backoff->first_event_time);
backoff->state = SPF_BACKOFF_QUIET;
backoff_debug("SPF Back-off(%s) HOLDDOWN elapsed, move to state %s",
switch (backoff->state) {
case SPF_BACKOFF_QUIET:
backoff->state = SPF_BACKOFF_SHORT_WAIT;
- thread_add_timer_msec(
+ event_add_timer_msec(
backoff->m, spf_backoff_timetolearn_elapsed, backoff,
backoff->timetolearn, &backoff->t_timetolearn);
- thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed,
- backoff, backoff->holddown,
- &backoff->t_holddown);
+ event_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed,
+ backoff, backoff->holddown,
+ &backoff->t_holddown);
backoff->first_event_time = now;
rv = backoff->init_delay;
break;
case SPF_BACKOFF_SHORT_WAIT:
case SPF_BACKOFF_LONG_WAIT:
- thread_cancel(&backoff->t_holddown);
- thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed,
- backoff, backoff->holddown,
- &backoff->t_holddown);
+ event_cancel(&backoff->t_holddown);
+ event_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed,
+ backoff, backoff->holddown,
+ &backoff->t_holddown);
if (backoff->state == SPF_BACKOFF_SHORT_WAIT)
rv = backoff->short_delay;
else
vty_out(vty, "%sHolddown timer: %ld msec\n", prefix,
backoff->holddown);
if (backoff->t_holddown) {
- struct timeval remain =
- thread_timer_remain(backoff->t_holddown);
+ struct timeval remain = event_timer_remain(backoff->t_holddown);
+
vty_out(vty, "%s Still runs for %lld msec\n",
prefix,
(long long)remain.tv_sec * 1000
backoff->timetolearn);
if (backoff->t_timetolearn) {
struct timeval remain =
- thread_timer_remain(backoff->t_timetolearn);
+ event_timer_remain(backoff->t_timetolearn);
vty_out(vty, "%s Still runs for %lld msec\n",
prefix,
(long long)remain.tv_sec * 1000
#endif
struct spf_backoff;
-struct thread_master;
+struct event_loop;
struct vty;
-struct spf_backoff *spf_backoff_new(struct thread_master *m, const char *name,
+struct spf_backoff *spf_backoff_new(struct event_loop *m, const char *name,
long init_delay, long short_delay,
long long_delay, long holddown,
long timetolearn);
lib/frrscript.c \
lib/frr_pthread.c \
lib/frrstr.c \
- lib/getopt.c \
- lib/getopt1.c \
lib/grammar_sandbox.c \
lib/graph.c \
lib/hash.c \
lib/systemd.c \
lib/table.c \
lib/termtable.c \
- lib/thread.c \
+ lib/event.c \
lib/typerb.c \
lib/typesafe.c \
lib/vector.c \
lib/plist.c \
lib/routemap.c \
lib/routemap_cli.c \
- lib/thread.c \
+ lib/event.c \
lib/vty.c \
lib/zlog_5424_cli.c \
# end
lib/frratomic.h \
lib/frrcu.h \
lib/frrstr.h \
- lib/getopt.h \
lib/graph.h \
lib/hash.h \
lib/hook.h \
lib/systemd.h \
lib/table.h \
lib/termtable.h \
- lib/thread.h \
+ lib/frrevent.h \
lib/trace.h \
lib/typerb.h \
lib/typesafe.h \
#include <zebra.h>
#include <sys/un.h>
-#include "thread.h"
+#include "frrevent.h"
#include "systemd.h"
#include "lib_errors.h"
systemd_send_information("STOPPING=1");
}
-static struct thread_master *systemd_master = NULL;
+static struct event_loop *systemd_master = NULL;
-static void systemd_send_watchdog(struct thread *t)
+static void systemd_send_watchdog(struct event *t)
{
systemd_send_information("WATCHDOG=1");
assert(watchdog_msec > 0);
- thread_add_timer_msec(systemd_master, systemd_send_watchdog, NULL,
- watchdog_msec, NULL);
+ event_add_timer_msec(systemd_master, systemd_send_watchdog, NULL,
+ watchdog_msec, NULL);
}
-void systemd_send_started(struct thread_master *m)
+void systemd_send_started(struct event_loop *m)
{
assert(m != NULL);
void systemd_send_stopping(void);
/*
- * master - The struct thread_master * to use to schedule ourself
+ * master - The struct event_loop * to use to schedule ourself
* the_process - Should we send watchdog if we are not the requested
* process?
*/
-void systemd_send_started(struct thread_master *master);
+void systemd_send_started(struct event_loop *master);
/*
* status - A status string to send to systemd
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* Thread management routine
- * Copyright (C) 1998, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
- */
-
-/* #define DEBUG */
-
-#include <zebra.h>
-#include <sys/resource.h>
-
-#include "thread.h"
-#include "memory.h"
-#include "frrcu.h"
-#include "log.h"
-#include "hash.h"
-#include "command.h"
-#include "sigevent.h"
-#include "network.h"
-#include "jhash.h"
-#include "frratomic.h"
-#include "frr_pthread.h"
-#include "lib_errors.h"
-#include "libfrr_trace.h"
-#include "libfrr.h"
-
-DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread");
-DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master");
-DEFINE_MTYPE_STATIC(LIB, THREAD_POLL, "Thread Poll Info");
-DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats");
-
-DECLARE_LIST(thread_list, struct thread, threaditem);
-
-struct cancel_req {
- int flags;
- struct thread *thread;
- void *eventobj;
- struct thread **threadref;
-};
-
-/* Flags for task cancellation */
-#define THREAD_CANCEL_FLAG_READY 0x01
-
-static int thread_timer_cmp(const struct thread *a, const struct thread *b)
-{
- if (a->u.sands.tv_sec < b->u.sands.tv_sec)
- return -1;
- if (a->u.sands.tv_sec > b->u.sands.tv_sec)
- return 1;
- if (a->u.sands.tv_usec < b->u.sands.tv_usec)
- return -1;
- if (a->u.sands.tv_usec > b->u.sands.tv_usec)
- return 1;
- return 0;
-}
-
-DECLARE_HEAP(thread_timer_list, struct thread, timeritem, thread_timer_cmp);
-
-#if defined(__APPLE__)
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#endif
-
-#define AWAKEN(m) \
- do { \
- const unsigned char wakebyte = 0x01; \
- write(m->io_pipe[1], &wakebyte, 1); \
- } while (0);
-
-/* control variable for initializer */
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-pthread_key_t thread_current;
-
-static pthread_mutex_t masters_mtx = PTHREAD_MUTEX_INITIALIZER;
-static struct list *masters;
-
-static void thread_free(struct thread_master *master, struct thread *thread);
-
-#ifndef EXCLUDE_CPU_TIME
-#define EXCLUDE_CPU_TIME 0
-#endif
-#ifndef CONSUMED_TIME_CHECK
-#define CONSUMED_TIME_CHECK 0
-#endif
-
-bool cputime_enabled = !EXCLUDE_CPU_TIME;
-unsigned long cputime_threshold = CONSUMED_TIME_CHECK;
-unsigned long walltime_threshold = CONSUMED_TIME_CHECK;
-
-/* CLI start ---------------------------------------------------------------- */
-#include "lib/thread_clippy.c"
-
-static unsigned int cpu_record_hash_key(const struct cpu_thread_history *a)
-{
- int size = sizeof(a->func);
-
- return jhash(&a->func, size, 0);
-}
-
-static bool cpu_record_hash_cmp(const struct cpu_thread_history *a,
- const struct cpu_thread_history *b)
-{
- return a->func == b->func;
-}
-
-static void *cpu_record_hash_alloc(struct cpu_thread_history *a)
-{
- struct cpu_thread_history *new;
- new = XCALLOC(MTYPE_THREAD_STATS, sizeof(struct cpu_thread_history));
- new->func = a->func;
- new->funcname = a->funcname;
- return new;
-}
-
-static void cpu_record_hash_free(void *a)
-{
- struct cpu_thread_history *hist = a;
-
- XFREE(MTYPE_THREAD_STATS, hist);
-}
-
-static void vty_out_cpu_thread_history(struct vty *vty,
- struct cpu_thread_history *a)
-{
- vty_out(vty,
- "%5zu %10zu.%03zu %9zu %8zu %9zu %8zu %9zu %9zu %9zu %10zu",
- a->total_active, a->cpu.total / 1000, a->cpu.total % 1000,
- a->total_calls, (a->cpu.total / a->total_calls), a->cpu.max,
- (a->real.total / a->total_calls), a->real.max,
- a->total_cpu_warn, a->total_wall_warn, a->total_starv_warn);
- vty_out(vty, " %c%c%c%c%c %s\n",
- a->types & (1 << THREAD_READ) ? 'R' : ' ',
- a->types & (1 << THREAD_WRITE) ? 'W' : ' ',
- a->types & (1 << THREAD_TIMER) ? 'T' : ' ',
- a->types & (1 << THREAD_EVENT) ? 'E' : ' ',
- a->types & (1 << THREAD_EXECUTE) ? 'X' : ' ', a->funcname);
-}
-
-static void cpu_record_hash_print(struct hash_bucket *bucket, void *args[])
-{
- struct cpu_thread_history *totals = args[0];
- struct cpu_thread_history copy;
- struct vty *vty = args[1];
- uint8_t *filter = args[2];
-
- struct cpu_thread_history *a = bucket->data;
-
- copy.total_active =
- atomic_load_explicit(&a->total_active, memory_order_seq_cst);
- copy.total_calls =
- atomic_load_explicit(&a->total_calls, memory_order_seq_cst);
- copy.total_cpu_warn =
- atomic_load_explicit(&a->total_cpu_warn, memory_order_seq_cst);
- copy.total_wall_warn =
- atomic_load_explicit(&a->total_wall_warn, memory_order_seq_cst);
- copy.total_starv_warn = atomic_load_explicit(&a->total_starv_warn,
- memory_order_seq_cst);
- copy.cpu.total =
- atomic_load_explicit(&a->cpu.total, memory_order_seq_cst);
- copy.cpu.max = atomic_load_explicit(&a->cpu.max, memory_order_seq_cst);
- copy.real.total =
- atomic_load_explicit(&a->real.total, memory_order_seq_cst);
- copy.real.max =
- atomic_load_explicit(&a->real.max, memory_order_seq_cst);
- copy.types = atomic_load_explicit(&a->types, memory_order_seq_cst);
- copy.funcname = a->funcname;
-
- if (!(copy.types & *filter))
- return;
-
- vty_out_cpu_thread_history(vty, ©);
- totals->total_active += copy.total_active;
- totals->total_calls += copy.total_calls;
- totals->total_cpu_warn += copy.total_cpu_warn;
- totals->total_wall_warn += copy.total_wall_warn;
- totals->total_starv_warn += copy.total_starv_warn;
- totals->real.total += copy.real.total;
- if (totals->real.max < copy.real.max)
- totals->real.max = copy.real.max;
- totals->cpu.total += copy.cpu.total;
- if (totals->cpu.max < copy.cpu.max)
- totals->cpu.max = copy.cpu.max;
-}
-
-static void cpu_record_print(struct vty *vty, uint8_t filter)
-{
- struct cpu_thread_history tmp;
- void *args[3] = {&tmp, vty, &filter};
- struct thread_master *m;
- struct listnode *ln;
-
- if (!cputime_enabled)
- vty_out(vty,
- "\n"
- "Collecting CPU time statistics is currently disabled. Following statistics\n"
- "will be zero or may display data from when collection was enabled. Use the\n"
- " \"service cputime-stats\" command to start collecting data.\n"
- "\nCounters and wallclock times are always maintained and should be accurate.\n");
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.funcname = "TOTAL";
- tmp.types = filter;
-
- frr_with_mutex (&masters_mtx) {
- for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) {
- const char *name = m->name ? m->name : "main";
-
- char underline[strlen(name) + 1];
- memset(underline, '-', sizeof(underline));
- underline[sizeof(underline) - 1] = '\0';
-
- vty_out(vty, "\n");
- vty_out(vty, "Showing statistics for pthread %s\n",
- name);
- vty_out(vty, "-------------------------------%s\n",
- underline);
- vty_out(vty, "%30s %18s %18s\n", "",
- "CPU (user+system):", "Real (wall-clock):");
- vty_out(vty,
- "Active Runtime(ms) Invoked Avg uSec Max uSecs");
- vty_out(vty, " Avg uSec Max uSecs");
- vty_out(vty,
- " CPU_Warn Wall_Warn Starv_Warn Type Thread\n");
-
- if (m->cpu_record->count)
- hash_iterate(
- m->cpu_record,
- (void (*)(struct hash_bucket *,
- void *))cpu_record_hash_print,
- args);
- else
- vty_out(vty, "No data to display yet.\n");
-
- vty_out(vty, "\n");
- }
- }
-
- vty_out(vty, "\n");
- vty_out(vty, "Total thread statistics\n");
- vty_out(vty, "-------------------------\n");
- vty_out(vty, "%30s %18s %18s\n", "",
- "CPU (user+system):", "Real (wall-clock):");
- vty_out(vty, "Active Runtime(ms) Invoked Avg uSec Max uSecs");
- vty_out(vty, " Avg uSec Max uSecs CPU_Warn Wall_Warn");
- vty_out(vty, " Type Thread\n");
-
- if (tmp.total_calls > 0)
- vty_out_cpu_thread_history(vty, &tmp);
-}
-
-static void cpu_record_hash_clear(struct hash_bucket *bucket, void *args[])
-{
- uint8_t *filter = args[0];
- struct hash *cpu_record = args[1];
-
- struct cpu_thread_history *a = bucket->data;
-
- if (!(a->types & *filter))
- return;
-
- hash_release(cpu_record, bucket->data);
-}
-
-static void cpu_record_clear(uint8_t filter)
-{
- uint8_t *tmp = &filter;
- struct thread_master *m;
- struct listnode *ln;
-
- frr_with_mutex (&masters_mtx) {
- for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) {
- frr_with_mutex (&m->mtx) {
- void *args[2] = {tmp, m->cpu_record};
- hash_iterate(
- m->cpu_record,
- (void (*)(struct hash_bucket *,
- void *))cpu_record_hash_clear,
- args);
- }
- }
- }
-}
-
-static uint8_t parse_filter(const char *filterstr)
-{
- int i = 0;
- int filter = 0;
-
- while (filterstr[i] != '\0') {
- switch (filterstr[i]) {
- case 'r':
- case 'R':
- filter |= (1 << THREAD_READ);
- break;
- case 'w':
- case 'W':
- filter |= (1 << THREAD_WRITE);
- break;
- case 't':
- case 'T':
- filter |= (1 << THREAD_TIMER);
- break;
- case 'e':
- case 'E':
- filter |= (1 << THREAD_EVENT);
- break;
- case 'x':
- case 'X':
- filter |= (1 << THREAD_EXECUTE);
- break;
- default:
- break;
- }
- ++i;
- }
- return filter;
-}
-
-DEFUN_NOSH (show_thread_cpu,
- show_thread_cpu_cmd,
- "show thread cpu [FILTER]",
- SHOW_STR
- "Thread information\n"
- "Thread CPU usage\n"
- "Display filter (rwtex)\n")
-{
- uint8_t filter = (uint8_t)-1U;
- int idx = 0;
-
- if (argv_find(argv, argc, "FILTER", &idx)) {
- filter = parse_filter(argv[idx]->arg);
- if (!filter) {
- vty_out(vty,
- "Invalid filter \"%s\" specified; must contain at leastone of 'RWTEXB'\n",
- argv[idx]->arg);
- return CMD_WARNING;
- }
- }
-
- cpu_record_print(vty, filter);
- return CMD_SUCCESS;
-}
-
-DEFPY (service_cputime_stats,
- service_cputime_stats_cmd,
- "[no] service cputime-stats",
- NO_STR
- "Set up miscellaneous service\n"
- "Collect CPU usage statistics\n")
-{
- cputime_enabled = !no;
- return CMD_SUCCESS;
-}
-
-DEFPY (service_cputime_warning,
- service_cputime_warning_cmd,
- "[no] service cputime-warning (1-4294967295)",
- NO_STR
- "Set up miscellaneous service\n"
- "Warn for tasks exceeding CPU usage threshold\n"
- "Warning threshold in milliseconds\n")
-{
- if (no)
- cputime_threshold = 0;
- else
- cputime_threshold = cputime_warning * 1000;
- return CMD_SUCCESS;
-}
-
-ALIAS (service_cputime_warning,
- no_service_cputime_warning_cmd,
- "no service cputime-warning",
- NO_STR
- "Set up miscellaneous service\n"
- "Warn for tasks exceeding CPU usage threshold\n")
-
-DEFPY (service_walltime_warning,
- service_walltime_warning_cmd,
- "[no] service walltime-warning (1-4294967295)",
- NO_STR
- "Set up miscellaneous service\n"
- "Warn for tasks exceeding total wallclock threshold\n"
- "Warning threshold in milliseconds\n")
-{
- if (no)
- walltime_threshold = 0;
- else
- walltime_threshold = walltime_warning * 1000;
- return CMD_SUCCESS;
-}
-
-ALIAS (service_walltime_warning,
- no_service_walltime_warning_cmd,
- "no service walltime-warning",
- NO_STR
- "Set up miscellaneous service\n"
- "Warn for tasks exceeding total wallclock threshold\n")
-
-static void show_thread_poll_helper(struct vty *vty, struct thread_master *m)
-{
- const char *name = m->name ? m->name : "main";
- char underline[strlen(name) + 1];
- struct thread *thread;
- uint32_t i;
-
- memset(underline, '-', sizeof(underline));
- underline[sizeof(underline) - 1] = '\0';
-
- vty_out(vty, "\nShowing poll FD's for %s\n", name);
- vty_out(vty, "----------------------%s\n", underline);
- vty_out(vty, "Count: %u/%d\n", (uint32_t)m->handler.pfdcount,
- m->fd_limit);
- for (i = 0; i < m->handler.pfdcount; i++) {
- vty_out(vty, "\t%6d fd:%6d events:%2d revents:%2d\t\t", i,
- m->handler.pfds[i].fd, m->handler.pfds[i].events,
- m->handler.pfds[i].revents);
-
- if (m->handler.pfds[i].events & POLLIN) {
- thread = m->read[m->handler.pfds[i].fd];
-
- if (!thread)
- vty_out(vty, "ERROR ");
- else
- vty_out(vty, "%s ", thread->xref->funcname);
- } else
- vty_out(vty, " ");
-
- if (m->handler.pfds[i].events & POLLOUT) {
- thread = m->write[m->handler.pfds[i].fd];
-
- if (!thread)
- vty_out(vty, "ERROR\n");
- else
- vty_out(vty, "%s\n", thread->xref->funcname);
- } else
- vty_out(vty, "\n");
- }
-}
-
-DEFUN_NOSH (show_thread_poll,
- show_thread_poll_cmd,
- "show thread poll",
- SHOW_STR
- "Thread information\n"
- "Show poll FD's and information\n")
-{
- struct listnode *node;
- struct thread_master *m;
-
- frr_with_mutex (&masters_mtx) {
- for (ALL_LIST_ELEMENTS_RO(masters, node, m)) {
- show_thread_poll_helper(vty, m);
- }
- }
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (clear_thread_cpu,
- clear_thread_cpu_cmd,
- "clear thread cpu [FILTER]",
- "Clear stored data in all pthreads\n"
- "Thread information\n"
- "Thread CPU usage\n"
- "Display filter (rwtexb)\n")
-{
- uint8_t filter = (uint8_t)-1U;
- int idx = 0;
-
- if (argv_find(argv, argc, "FILTER", &idx)) {
- filter = parse_filter(argv[idx]->arg);
- if (!filter) {
- vty_out(vty,
- "Invalid filter \"%s\" specified; must contain at leastone of 'RWTEXB'\n",
- argv[idx]->arg);
- return CMD_WARNING;
- }
- }
-
- cpu_record_clear(filter);
- return CMD_SUCCESS;
-}
-
-static void show_thread_timers_helper(struct vty *vty, struct thread_master *m)
-{
- const char *name = m->name ? m->name : "main";
- char underline[strlen(name) + 1];
- struct thread *thread;
-
- memset(underline, '-', sizeof(underline));
- underline[sizeof(underline) - 1] = '\0';
-
- vty_out(vty, "\nShowing timers for %s\n", name);
- vty_out(vty, "-------------------%s\n", underline);
-
- frr_each (thread_timer_list, &m->timer, thread) {
- vty_out(vty, " %-50s%pTH\n", thread->hist->funcname, thread);
- }
-}
-
-DEFPY_NOSH (show_thread_timers,
- show_thread_timers_cmd,
- "show thread timers",
- SHOW_STR
- "Thread information\n"
- "Show all timers and how long they have in the system\n")
-{
- struct listnode *node;
- struct thread_master *m;
-
- frr_with_mutex (&masters_mtx) {
- for (ALL_LIST_ELEMENTS_RO(masters, node, m))
- show_thread_timers_helper(vty, m);
- }
-
- return CMD_SUCCESS;
-}
-
-void thread_cmd_init(void)
-{
- install_element(VIEW_NODE, &show_thread_cpu_cmd);
- install_element(VIEW_NODE, &show_thread_poll_cmd);
- install_element(ENABLE_NODE, &clear_thread_cpu_cmd);
-
- install_element(CONFIG_NODE, &service_cputime_stats_cmd);
- install_element(CONFIG_NODE, &service_cputime_warning_cmd);
- install_element(CONFIG_NODE, &no_service_cputime_warning_cmd);
- install_element(CONFIG_NODE, &service_walltime_warning_cmd);
- install_element(CONFIG_NODE, &no_service_walltime_warning_cmd);
-
- install_element(VIEW_NODE, &show_thread_timers_cmd);
-}
-/* CLI end ------------------------------------------------------------------ */
-
-
-static void cancelreq_del(void *cr)
-{
- XFREE(MTYPE_TMP, cr);
-}
-
-/* initializer, only ever called once */
-static void initializer(void)
-{
- pthread_key_create(&thread_current, NULL);
-}
-
-struct thread_master *thread_master_create(const char *name)
-{
- struct thread_master *rv;
- struct rlimit limit;
-
- pthread_once(&init_once, &initializer);
-
- rv = XCALLOC(MTYPE_THREAD_MASTER, sizeof(struct thread_master));
-
- /* Initialize master mutex */
- pthread_mutex_init(&rv->mtx, NULL);
- pthread_cond_init(&rv->cancel_cond, NULL);
-
- /* Set name */
- name = name ? name : "default";
- rv->name = XSTRDUP(MTYPE_THREAD_MASTER, name);
-
- /* Initialize I/O task data structures */
-
- /* Use configured limit if present, ulimit otherwise. */
- rv->fd_limit = frr_get_fd_limit();
- if (rv->fd_limit == 0) {
- getrlimit(RLIMIT_NOFILE, &limit);
- rv->fd_limit = (int)limit.rlim_cur;
- }
-
- rv->read = XCALLOC(MTYPE_THREAD_POLL,
- sizeof(struct thread *) * rv->fd_limit);
-
- rv->write = XCALLOC(MTYPE_THREAD_POLL,
- sizeof(struct thread *) * rv->fd_limit);
-
- char tmhashname[strlen(name) + 32];
- snprintf(tmhashname, sizeof(tmhashname), "%s - threadmaster event hash",
- name);
- rv->cpu_record = hash_create_size(
- 8, (unsigned int (*)(const void *))cpu_record_hash_key,
- (bool (*)(const void *, const void *))cpu_record_hash_cmp,
- tmhashname);
-
- thread_list_init(&rv->event);
- thread_list_init(&rv->ready);
- thread_list_init(&rv->unuse);
- thread_timer_list_init(&rv->timer);
-
- /* Initialize thread_fetch() settings */
- rv->spin = true;
- rv->handle_signals = true;
-
- /* Set pthread owner, should be updated by actual owner */
- rv->owner = pthread_self();
- rv->cancel_req = list_new();
- rv->cancel_req->del = cancelreq_del;
- rv->canceled = true;
-
- /* Initialize pipe poker */
- pipe(rv->io_pipe);
- set_nonblocking(rv->io_pipe[0]);
- set_nonblocking(rv->io_pipe[1]);
-
- /* Initialize data structures for poll() */
- rv->handler.pfdsize = rv->fd_limit;
- rv->handler.pfdcount = 0;
- rv->handler.pfds = XCALLOC(MTYPE_THREAD_MASTER,
- sizeof(struct pollfd) * rv->handler.pfdsize);
- rv->handler.copy = XCALLOC(MTYPE_THREAD_MASTER,
- sizeof(struct pollfd) * rv->handler.pfdsize);
-
- /* add to list of threadmasters */
- frr_with_mutex (&masters_mtx) {
- if (!masters)
- masters = list_new();
-
- listnode_add(masters, rv);
- }
-
- return rv;
-}
-
-void thread_master_set_name(struct thread_master *master, const char *name)
-{
- frr_with_mutex (&master->mtx) {
- XFREE(MTYPE_THREAD_MASTER, master->name);
- master->name = XSTRDUP(MTYPE_THREAD_MASTER, name);
- }
-}
-
-#define THREAD_UNUSED_DEPTH 10
-
-/* Move thread to unuse list. */
-static void thread_add_unuse(struct thread_master *m, struct thread *thread)
-{
- pthread_mutex_t mtxc = thread->mtx;
-
- assert(m != NULL && thread != NULL);
-
- thread->hist->total_active--;
- memset(thread, 0, sizeof(struct thread));
- thread->type = THREAD_UNUSED;
-
- /* Restore the thread mutex context. */
- thread->mtx = mtxc;
-
- if (thread_list_count(&m->unuse) < THREAD_UNUSED_DEPTH) {
- thread_list_add_tail(&m->unuse, thread);
- return;
- }
-
- thread_free(m, thread);
-}
-
-/* Free all unused thread. */
-static void thread_list_free(struct thread_master *m,
- struct thread_list_head *list)
-{
- struct thread *t;
-
- while ((t = thread_list_pop(list)))
- thread_free(m, t);
-}
-
-static void thread_array_free(struct thread_master *m,
- struct thread **thread_array)
-{
- struct thread *t;
- int index;
-
- for (index = 0; index < m->fd_limit; ++index) {
- t = thread_array[index];
- if (t) {
- thread_array[index] = NULL;
- thread_free(m, t);
- }
- }
- XFREE(MTYPE_THREAD_POLL, thread_array);
-}
-
-/*
- * thread_master_free_unused
- *
- * As threads are finished with they are put on the
- * unuse list for later reuse.
- * If we are shutting down, Free up unused threads
- * So we can see if we forget to shut anything off
- */
-void thread_master_free_unused(struct thread_master *m)
-{
- frr_with_mutex (&m->mtx) {
- struct thread *t;
- while ((t = thread_list_pop(&m->unuse)))
- thread_free(m, t);
- }
-}
-
-/* Stop thread scheduler. */
-void thread_master_free(struct thread_master *m)
-{
- struct thread *t;
-
- frr_with_mutex (&masters_mtx) {
- listnode_delete(masters, m);
- if (masters->count == 0) {
- list_delete(&masters);
- }
- }
-
- thread_array_free(m, m->read);
- thread_array_free(m, m->write);
- while ((t = thread_timer_list_pop(&m->timer)))
- thread_free(m, t);
- thread_list_free(m, &m->event);
- thread_list_free(m, &m->ready);
- thread_list_free(m, &m->unuse);
- pthread_mutex_destroy(&m->mtx);
- pthread_cond_destroy(&m->cancel_cond);
- close(m->io_pipe[0]);
- close(m->io_pipe[1]);
- list_delete(&m->cancel_req);
- m->cancel_req = NULL;
-
- hash_clean(m->cpu_record, cpu_record_hash_free);
- hash_free(m->cpu_record);
- m->cpu_record = NULL;
-
- XFREE(MTYPE_THREAD_MASTER, m->name);
- XFREE(MTYPE_THREAD_MASTER, m->handler.pfds);
- XFREE(MTYPE_THREAD_MASTER, m->handler.copy);
- XFREE(MTYPE_THREAD_MASTER, m);
-}
-
-/* Return remain time in milliseconds. */
-unsigned long thread_timer_remain_msec(struct thread *thread)
-{
- int64_t remain;
-
- if (!thread_is_scheduled(thread))
- return 0;
-
- frr_with_mutex (&thread->mtx) {
- remain = monotime_until(&thread->u.sands, NULL) / 1000LL;
- }
-
- return remain < 0 ? 0 : remain;
-}
-
-/* Return remain time in seconds. */
-unsigned long thread_timer_remain_second(struct thread *thread)
-{
- return thread_timer_remain_msec(thread) / 1000LL;
-}
-
-struct timeval thread_timer_remain(struct thread *thread)
-{
- struct timeval remain;
- frr_with_mutex (&thread->mtx) {
- monotime_until(&thread->u.sands, &remain);
- }
- return remain;
-}
-
-static int time_hhmmss(char *buf, int buf_size, long sec)
-{
- long hh;
- long mm;
- int wr;
-
- assert(buf_size >= 8);
-
- hh = sec / 3600;
- sec %= 3600;
- mm = sec / 60;
- sec %= 60;
-
- wr = snprintf(buf, buf_size, "%02ld:%02ld:%02ld", hh, mm, sec);
-
- return wr != 8;
-}
-
-char *thread_timer_to_hhmmss(char *buf, int buf_size,
- struct thread *t_timer)
-{
- if (t_timer) {
- time_hhmmss(buf, buf_size,
- thread_timer_remain_second(t_timer));
- } else {
- snprintf(buf, buf_size, "--:--:--");
- }
- return buf;
-}
-
-/* Get new thread. */
-static struct thread *thread_get(struct thread_master *m, uint8_t type,
- void (*func)(struct thread *), void *arg,
- const struct xref_threadsched *xref)
-{
- struct thread *thread = thread_list_pop(&m->unuse);
- struct cpu_thread_history tmp;
-
- if (!thread) {
- thread = XCALLOC(MTYPE_THREAD, sizeof(struct thread));
- /* mutex only needs to be initialized at struct creation. */
- pthread_mutex_init(&thread->mtx, NULL);
- m->alloc++;
- }
-
- thread->type = type;
- thread->add_type = type;
- thread->master = m;
- thread->arg = arg;
- thread->yield = THREAD_YIELD_TIME_SLOT; /* default */
- thread->ref = NULL;
- thread->ignore_timer_late = false;
-
- /*
- * So if the passed in funcname is not what we have
- * stored that means the thread->hist needs to be
- * updated. We keep the last one around in unused
- * under the assumption that we are probably
- * going to immediately allocate the same
- * type of thread.
- * This hopefully saves us some serious
- * hash_get lookups.
- */
- if ((thread->xref && thread->xref->funcname != xref->funcname)
- || thread->func != func) {
- tmp.func = func;
- tmp.funcname = xref->funcname;
- thread->hist =
- hash_get(m->cpu_record, &tmp,
- (void *(*)(void *))cpu_record_hash_alloc);
- }
- thread->hist->total_active++;
- thread->func = func;
- thread->xref = xref;
-
- return thread;
-}
-
-static void thread_free(struct thread_master *master, struct thread *thread)
-{
- /* Update statistics. */
- assert(master->alloc > 0);
- master->alloc--;
-
- /* Free allocated resources. */
- pthread_mutex_destroy(&thread->mtx);
- XFREE(MTYPE_THREAD, thread);
-}
-
-static int fd_poll(struct thread_master *m, const struct timeval *timer_wait,
- bool *eintr_p)
-{
- sigset_t origsigs;
- unsigned char trash[64];
- nfds_t count = m->handler.copycount;
-
- /*
- * If timer_wait is null here, that means poll() should block
- * indefinitely, unless the thread_master has overridden it by setting
- * ->selectpoll_timeout.
- *
- * If the value is positive, it specifies the maximum number of
- * milliseconds to wait. If the timeout is -1, it specifies that
- * we should never wait and always return immediately even if no
- * event is detected. If the value is zero, the behavior is default.
- */
- int timeout = -1;
-
- /* number of file descriptors with events */
- int num;
-
- if (timer_wait != NULL
- && m->selectpoll_timeout == 0) // use the default value
- timeout = (timer_wait->tv_sec * 1000)
- + (timer_wait->tv_usec / 1000);
- else if (m->selectpoll_timeout > 0) // use the user's timeout
- timeout = m->selectpoll_timeout;
- else if (m->selectpoll_timeout
- < 0) // effect a poll (return immediately)
- timeout = 0;
-
- zlog_tls_buffer_flush();
- rcu_read_unlock();
- rcu_assert_read_unlocked();
-
- /* add poll pipe poker */
- assert(count + 1 < m->handler.pfdsize);
- m->handler.copy[count].fd = m->io_pipe[0];
- m->handler.copy[count].events = POLLIN;
- m->handler.copy[count].revents = 0x00;
-
- /* We need to deal with a signal-handling race here: we
- * don't want to miss a crucial signal, such as SIGTERM or SIGINT,
- * that may arrive just before we enter poll(). We will block the
- * key signals, then check whether any have arrived - if so, we return
- * before calling poll(). If not, we'll re-enable the signals
- * in the ppoll() call.
- */
-
- sigemptyset(&origsigs);
- if (m->handle_signals) {
- /* Main pthread that handles the app signals */
- if (frr_sigevent_check(&origsigs)) {
- /* Signal to process - restore signal mask and return */
- pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
- num = -1;
- *eintr_p = true;
- goto done;
- }
- } else {
- /* Don't make any changes for the non-main pthreads */
- pthread_sigmask(SIG_SETMASK, NULL, &origsigs);
- }
-
-#if defined(HAVE_PPOLL)
- struct timespec ts, *tsp;
-
- if (timeout >= 0) {
- ts.tv_sec = timeout / 1000;
- ts.tv_nsec = (timeout % 1000) * 1000000;
- tsp = &ts;
- } else
- tsp = NULL;
-
- num = ppoll(m->handler.copy, count + 1, tsp, &origsigs);
- pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
-#else
- /* Not ideal - there is a race after we restore the signal mask */
- pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
- num = poll(m->handler.copy, count + 1, timeout);
-#endif
-
-done:
-
- if (num < 0 && errno == EINTR)
- *eintr_p = true;
-
- if (num > 0 && m->handler.copy[count].revents != 0 && num--)
- while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0)
- ;
-
- rcu_read_lock();
-
- return num;
-}
-
-/* Add new read thread. */
-void _thread_add_read_write(const struct xref_threadsched *xref,
- struct thread_master *m,
- void (*func)(struct thread *), void *arg, int fd,
- struct thread **t_ptr)
-{
- int dir = xref->thread_type;
- struct thread *thread = NULL;
- struct thread **thread_array;
-
- if (dir == THREAD_READ)
- frrtrace(9, frr_libfrr, schedule_read, m,
- xref->funcname, xref->xref.file, xref->xref.line,
- t_ptr, fd, 0, arg, 0);
- else
- frrtrace(9, frr_libfrr, schedule_write, m,
- xref->funcname, xref->xref.file, xref->xref.line,
- t_ptr, fd, 0, arg, 0);
-
- assert(fd >= 0);
- if (fd >= m->fd_limit)
- assert(!"Number of FD's open is greater than FRR currently configured to handle, aborting");
-
- frr_with_mutex (&m->mtx) {
- if (t_ptr && *t_ptr)
- // thread is already scheduled; don't reschedule
- break;
-
- /* default to a new pollfd */
- nfds_t queuepos = m->handler.pfdcount;
-
- if (dir == THREAD_READ)
- thread_array = m->read;
- else
- thread_array = m->write;
-
- /* if we already have a pollfd for our file descriptor, find and
- * use it */
- for (nfds_t i = 0; i < m->handler.pfdcount; i++)
- if (m->handler.pfds[i].fd == fd) {
- queuepos = i;
-
-#ifdef DEV_BUILD
- /*
- * What happens if we have a thread already
- * created for this event?
- */
- if (thread_array[fd])
- assert(!"Thread already scheduled for file descriptor");
-#endif
- break;
- }
-
- /* make sure we have room for this fd + pipe poker fd */
- assert(queuepos + 1 < m->handler.pfdsize);
-
- thread = thread_get(m, dir, func, arg, xref);
-
- m->handler.pfds[queuepos].fd = fd;
- m->handler.pfds[queuepos].events |=
- (dir == THREAD_READ ? POLLIN : POLLOUT);
-
- if (queuepos == m->handler.pfdcount)
- m->handler.pfdcount++;
-
- if (thread) {
- frr_with_mutex (&thread->mtx) {
- thread->u.fd = fd;
- thread_array[thread->u.fd] = thread;
- }
-
- if (t_ptr) {
- *t_ptr = thread;
- thread->ref = t_ptr;
- }
- }
-
- AWAKEN(m);
- }
-}
-
-static void _thread_add_timer_timeval(const struct xref_threadsched *xref,
- struct thread_master *m,
- void (*func)(struct thread *), void *arg,
- struct timeval *time_relative,
- struct thread **t_ptr)
-{
- struct thread *thread;
- struct timeval t;
-
- assert(m != NULL);
-
- assert(time_relative);
-
- frrtrace(9, frr_libfrr, schedule_timer, m,
- xref->funcname, xref->xref.file, xref->xref.line,
- t_ptr, 0, 0, arg, (long)time_relative->tv_sec);
-
- /* Compute expiration/deadline time. */
- monotime(&t);
- timeradd(&t, time_relative, &t);
-
- frr_with_mutex (&m->mtx) {
- if (t_ptr && *t_ptr)
- /* thread is already scheduled; don't reschedule */
- return;
-
- thread = thread_get(m, THREAD_TIMER, func, arg, xref);
-
- frr_with_mutex (&thread->mtx) {
- thread->u.sands = t;
- thread_timer_list_add(&m->timer, thread);
- if (t_ptr) {
- *t_ptr = thread;
- thread->ref = t_ptr;
- }
- }
-
- /* The timer list is sorted - if this new timer
- * might change the time we'll wait for, give the pthread
- * a chance to re-compute.
- */
- if (thread_timer_list_first(&m->timer) == thread)
- AWAKEN(m);
- }
-#define ONEYEAR2SEC (60 * 60 * 24 * 365)
- if (time_relative->tv_sec > ONEYEAR2SEC)
- flog_err(
- EC_LIB_TIMER_TOO_LONG,
- "Timer: %pTHD is created with an expiration that is greater than 1 year",
- thread);
-}
-
-
-/* Add timer event thread. */
-void _thread_add_timer(const struct xref_threadsched *xref,
- struct thread_master *m, void (*func)(struct thread *),
- void *arg, long timer, struct thread **t_ptr)
-{
- struct timeval trel;
-
- assert(m != NULL);
-
- trel.tv_sec = timer;
- trel.tv_usec = 0;
-
- _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
-}
-
-/* Add timer event thread with "millisecond" resolution */
-void _thread_add_timer_msec(const struct xref_threadsched *xref,
- struct thread_master *m,
- void (*func)(struct thread *), void *arg,
- long timer, struct thread **t_ptr)
-{
- struct timeval trel;
-
- assert(m != NULL);
-
- trel.tv_sec = timer / 1000;
- trel.tv_usec = 1000 * (timer % 1000);
-
- _thread_add_timer_timeval(xref, m, func, arg, &trel, t_ptr);
-}
-
-/* Add timer event thread with "timeval" resolution */
-void _thread_add_timer_tv(const struct xref_threadsched *xref,
- struct thread_master *m,
- void (*func)(struct thread *), void *arg,
- struct timeval *tv, struct thread **t_ptr)
-{
- _thread_add_timer_timeval(xref, m, func, arg, tv, t_ptr);
-}
-
-/* Add simple event thread. */
-void _thread_add_event(const struct xref_threadsched *xref,
- struct thread_master *m, void (*func)(struct thread *),
- void *arg, int val, struct thread **t_ptr)
-{
- struct thread *thread = NULL;
-
- frrtrace(9, frr_libfrr, schedule_event, m,
- xref->funcname, xref->xref.file, xref->xref.line,
- t_ptr, 0, val, arg, 0);
-
- assert(m != NULL);
-
- frr_with_mutex (&m->mtx) {
- if (t_ptr && *t_ptr)
- /* thread is already scheduled; don't reschedule */
- break;
-
- thread = thread_get(m, THREAD_EVENT, func, arg, xref);
- frr_with_mutex (&thread->mtx) {
- thread->u.val = val;
- thread_list_add_tail(&m->event, thread);
- }
-
- if (t_ptr) {
- *t_ptr = thread;
- thread->ref = t_ptr;
- }
-
- AWAKEN(m);
- }
-}
-
-/* Thread cancellation ------------------------------------------------------ */
-
-/**
- * NOT's out the .events field of pollfd corresponding to the given file
- * descriptor. The event to be NOT'd is passed in the 'state' parameter.
- *
- * This needs to happen for both copies of pollfd's. See 'thread_fetch'
- * implementation for details.
- *
- * @param master
- * @param fd
- * @param state the event to cancel. One or more (OR'd together) of the
- * following:
- * - POLLIN
- * - POLLOUT
- */
-static void thread_cancel_rw(struct thread_master *master, int fd, short state,
- int idx_hint)
-{
- bool found = false;
-
- /* find the index of corresponding pollfd */
- nfds_t i;
-
- /* Cancel POLLHUP too just in case some bozo set it */
- state |= POLLHUP;
-
- /* Some callers know the index of the pfd already */
- if (idx_hint >= 0) {
- i = idx_hint;
- found = true;
- } else {
- /* Have to look for the fd in the pfd array */
- for (i = 0; i < master->handler.pfdcount; i++)
- if (master->handler.pfds[i].fd == fd) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- zlog_debug(
- "[!] Received cancellation request for nonexistent rw job");
- zlog_debug("[!] threadmaster: %s | fd: %d",
- master->name ? master->name : "", fd);
- return;
- }
-
- /* NOT out event. */
- master->handler.pfds[i].events &= ~(state);
-
- /* If all events are canceled, delete / resize the pollfd array. */
- if (master->handler.pfds[i].events == 0) {
- memmove(master->handler.pfds + i, master->handler.pfds + i + 1,
- (master->handler.pfdcount - i - 1)
- * sizeof(struct pollfd));
- master->handler.pfdcount--;
- master->handler.pfds[master->handler.pfdcount].fd = 0;
- master->handler.pfds[master->handler.pfdcount].events = 0;
- }
-
- /* If we have the same pollfd in the copy, perform the same operations,
- * otherwise return. */
- if (i >= master->handler.copycount)
- return;
-
- master->handler.copy[i].events &= ~(state);
-
- if (master->handler.copy[i].events == 0) {
- memmove(master->handler.copy + i, master->handler.copy + i + 1,
- (master->handler.copycount - i - 1)
- * sizeof(struct pollfd));
- master->handler.copycount--;
- master->handler.copy[master->handler.copycount].fd = 0;
- master->handler.copy[master->handler.copycount].events = 0;
- }
-}
-
-/*
- * Process task cancellation given a task argument: iterate through the
- * various lists of tasks, looking for any that match the argument.
- */
-static void cancel_arg_helper(struct thread_master *master,
- const struct cancel_req *cr)
-{
- struct thread *t;
- nfds_t i;
- int fd;
- struct pollfd *pfd;
-
- /* We're only processing arg-based cancellations here. */
- if (cr->eventobj == NULL)
- return;
-
- /* First process the ready lists. */
- frr_each_safe(thread_list, &master->event, t) {
- if (t->arg != cr->eventobj)
- continue;
- thread_list_del(&master->event, t);
- if (t->ref)
- *t->ref = NULL;
- thread_add_unuse(master, t);
- }
-
- frr_each_safe(thread_list, &master->ready, t) {
- if (t->arg != cr->eventobj)
- continue;
- thread_list_del(&master->ready, t);
- if (t->ref)
- *t->ref = NULL;
- thread_add_unuse(master, t);
- }
-
- /* If requested, stop here and ignore io and timers */
- if (CHECK_FLAG(cr->flags, THREAD_CANCEL_FLAG_READY))
- return;
-
- /* Check the io tasks */
- for (i = 0; i < master->handler.pfdcount;) {
- pfd = master->handler.pfds + i;
-
- if (pfd->events & POLLIN)
- t = master->read[pfd->fd];
- else
- t = master->write[pfd->fd];
-
- if (t && t->arg == cr->eventobj) {
- fd = pfd->fd;
-
- /* Found a match to cancel: clean up fd arrays */
- thread_cancel_rw(master, pfd->fd, pfd->events, i);
-
- /* Clean up thread arrays */
- master->read[fd] = NULL;
- master->write[fd] = NULL;
-
- /* Clear caller's ref */
- if (t->ref)
- *t->ref = NULL;
-
- thread_add_unuse(master, t);
-
- /* Don't increment 'i' since the cancellation will have
- * removed the entry from the pfd array
- */
- } else
- i++;
- }
-
- /* Check the timer tasks */
- t = thread_timer_list_first(&master->timer);
- while (t) {
- struct thread *t_next;
-
- t_next = thread_timer_list_next(&master->timer, t);
-
- if (t->arg == cr->eventobj) {
- thread_timer_list_del(&master->timer, t);
- if (t->ref)
- *t->ref = NULL;
- thread_add_unuse(master, t);
- }
-
- t = t_next;
- }
-}
-
-/**
- * Process cancellation requests.
- *
- * This may only be run from the pthread which owns the thread_master.
- *
- * @param master the thread master to process
- * @REQUIRE master->mtx
- */
-static void do_thread_cancel(struct thread_master *master)
-{
- struct thread_list_head *list = NULL;
- struct thread **thread_array = NULL;
- struct thread *thread;
- struct cancel_req *cr;
- struct listnode *ln;
-
- for (ALL_LIST_ELEMENTS_RO(master->cancel_req, ln, cr)) {
- /*
- * If this is an event object cancellation, search
- * through task lists deleting any tasks which have the
- * specified argument - use this handy helper function.
- */
- if (cr->eventobj) {
- cancel_arg_helper(master, cr);
- continue;
- }
-
- /*
- * The pointer varies depending on whether the cancellation
- * request was made asynchronously or not. If it was, we
- * need to check whether the thread even exists anymore
- * before cancelling it.
- */
- thread = (cr->thread) ? cr->thread : *cr->threadref;
-
- if (!thread)
- continue;
-
- list = NULL;
- thread_array = NULL;
-
- /* Determine the appropriate queue to cancel the thread from */
- switch (thread->type) {
- case THREAD_READ:
- thread_cancel_rw(master, thread->u.fd, POLLIN, -1);
- thread_array = master->read;
- break;
- case THREAD_WRITE:
- thread_cancel_rw(master, thread->u.fd, POLLOUT, -1);
- thread_array = master->write;
- break;
- case THREAD_TIMER:
- thread_timer_list_del(&master->timer, thread);
- break;
- case THREAD_EVENT:
- list = &master->event;
- break;
- case THREAD_READY:
- list = &master->ready;
- break;
- default:
- continue;
- break;
- }
-
- if (list) {
- thread_list_del(list, thread);
- } else if (thread_array) {
- thread_array[thread->u.fd] = NULL;
- }
-
- if (thread->ref)
- *thread->ref = NULL;
-
- thread_add_unuse(thread->master, thread);
- }
-
- /* Delete and free all cancellation requests */
- if (master->cancel_req)
- list_delete_all_node(master->cancel_req);
-
- /* Wake up any threads which may be blocked in thread_cancel_async() */
- master->canceled = true;
- pthread_cond_broadcast(&master->cancel_cond);
-}
-
-/*
- * Helper function used for multiple flavors of arg-based cancellation.
- */
-static void cancel_event_helper(struct thread_master *m, void *arg, int flags)
-{
- struct cancel_req *cr;
-
- assert(m->owner == pthread_self());
-
- /* Only worth anything if caller supplies an arg. */
- if (arg == NULL)
- return;
-
- cr = XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
-
- cr->flags = flags;
-
- frr_with_mutex (&m->mtx) {
- cr->eventobj = arg;
- listnode_add(m->cancel_req, cr);
- do_thread_cancel(m);
- }
-}
-
-/**
- * Cancel any events which have the specified argument.
- *
- * MT-Unsafe
- *
- * @param m the thread_master to cancel from
- * @param arg the argument passed when creating the event
- */
-void thread_cancel_event(struct thread_master *master, void *arg)
-{
- cancel_event_helper(master, arg, 0);
-}
-
-/*
- * Cancel ready tasks with an arg matching 'arg'
- *
- * MT-Unsafe
- *
- * @param m the thread_master to cancel from
- * @param arg the argument passed when creating the event
- */
-void thread_cancel_event_ready(struct thread_master *m, void *arg)
-{
-
- /* Only cancel ready/event tasks */
- cancel_event_helper(m, arg, THREAD_CANCEL_FLAG_READY);
-}
-
-/**
- * Cancel a specific task.
- *
- * MT-Unsafe
- *
- * @param thread task to cancel
- */
-void thread_cancel(struct thread **thread)
-{
- struct thread_master *master;
-
- if (thread == NULL || *thread == NULL)
- return;
-
- master = (*thread)->master;
-
- frrtrace(9, frr_libfrr, thread_cancel, master,
- (*thread)->xref->funcname, (*thread)->xref->xref.file,
- (*thread)->xref->xref.line, NULL, (*thread)->u.fd,
- (*thread)->u.val, (*thread)->arg, (*thread)->u.sands.tv_sec);
-
- assert(master->owner == pthread_self());
-
- frr_with_mutex (&master->mtx) {
- struct cancel_req *cr =
- XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
- cr->thread = *thread;
- listnode_add(master->cancel_req, cr);
- do_thread_cancel(master);
- }
-
- *thread = NULL;
-}
-
-/**
- * Asynchronous cancellation.
- *
- * Called with either a struct thread ** or void * to an event argument,
- * this function posts the correct cancellation request and blocks until it is
- * serviced.
- *
- * If the thread is currently running, execution blocks until it completes.
- *
- * The last two parameters are mutually exclusive, i.e. if you pass one the
- * other must be NULL.
- *
- * When the cancellation procedure executes on the target thread_master, the
- * thread * provided is checked for nullity. If it is null, the thread is
- * assumed to no longer exist and the cancellation request is a no-op. Thus
- * users of this API must pass a back-reference when scheduling the original
- * task.
- *
- * MT-Safe
- *
- * @param master the thread master with the relevant event / task
- * @param thread pointer to thread to cancel
- * @param eventobj the event
- */
-void thread_cancel_async(struct thread_master *master, struct thread **thread,
- void *eventobj)
-{
- assert(!(thread && eventobj) && (thread || eventobj));
-
- if (thread && *thread)
- frrtrace(9, frr_libfrr, thread_cancel_async, master,
- (*thread)->xref->funcname, (*thread)->xref->xref.file,
- (*thread)->xref->xref.line, NULL, (*thread)->u.fd,
- (*thread)->u.val, (*thread)->arg,
- (*thread)->u.sands.tv_sec);
- else
- frrtrace(9, frr_libfrr, thread_cancel_async, master, NULL, NULL,
- 0, NULL, 0, 0, eventobj, 0);
-
- assert(master->owner != pthread_self());
-
- frr_with_mutex (&master->mtx) {
- master->canceled = false;
-
- if (thread) {
- struct cancel_req *cr =
- XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
- cr->threadref = thread;
- listnode_add(master->cancel_req, cr);
- } else if (eventobj) {
- struct cancel_req *cr =
- XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
- cr->eventobj = eventobj;
- listnode_add(master->cancel_req, cr);
- }
- AWAKEN(master);
-
- while (!master->canceled)
- pthread_cond_wait(&master->cancel_cond, &master->mtx);
- }
-
- if (thread)
- *thread = NULL;
-}
-/* ------------------------------------------------------------------------- */
-
-static struct timeval *thread_timer_wait(struct thread_timer_list_head *timers,
- struct timeval *timer_val)
-{
- if (!thread_timer_list_count(timers))
- return NULL;
-
- struct thread *next_timer = thread_timer_list_first(timers);
- monotime_until(&next_timer->u.sands, timer_val);
- return timer_val;
-}
-
-static struct thread *thread_run(struct thread_master *m, struct thread *thread,
- struct thread *fetch)
-{
- *fetch = *thread;
- thread_add_unuse(m, thread);
- return fetch;
-}
-
-static int thread_process_io_helper(struct thread_master *m,
- struct thread *thread, short state,
- short actual_state, int pos)
-{
- struct thread **thread_array;
-
- /*
- * poll() clears the .events field, but the pollfd array we
- * pass to poll() is a copy of the one used to schedule threads.
- * We need to synchronize state between the two here by applying
- * the same changes poll() made on the copy of the "real" pollfd
- * array.
- *
- * This cleans up a possible infinite loop where we refuse
- * to respond to a poll event but poll is insistent that
- * we should.
- */
- m->handler.pfds[pos].events &= ~(state);
-
- if (!thread) {
- if ((actual_state & (POLLHUP|POLLIN)) != POLLHUP)
- flog_err(EC_LIB_NO_THREAD,
- "Attempting to process an I/O event but for fd: %d(%d) no thread to handle this!",
- m->handler.pfds[pos].fd, actual_state);
- return 0;
- }
-
- if (thread->type == THREAD_READ)
- thread_array = m->read;
- else
- thread_array = m->write;
-
- thread_array[thread->u.fd] = NULL;
- thread_list_add_tail(&m->ready, thread);
- thread->type = THREAD_READY;
-
- return 1;
-}
-
-/**
- * Process I/O events.
- *
- * Walks through file descriptor array looking for those pollfds whose .revents
- * field has something interesting. Deletes any invalid file descriptors.
- *
- * @param m the thread master
- * @param num the number of active file descriptors (return value of poll())
- */
-static void thread_process_io(struct thread_master *m, unsigned int num)
-{
- unsigned int ready = 0;
- struct pollfd *pfds = m->handler.copy;
-
- for (nfds_t i = 0; i < m->handler.copycount && ready < num; ++i) {
- /* no event for current fd? immediately continue */
- if (pfds[i].revents == 0)
- continue;
-
- ready++;
-
- /*
- * Unless someone has called thread_cancel from another
- * pthread, the only thing that could have changed in
- * m->handler.pfds while we were asleep is the .events
- * field in a given pollfd. Barring thread_cancel() that
- * value should be a superset of the values we have in our
- * copy, so there's no need to update it. Similarily,
- * barring deletion, the fd should still be a valid index
- * into the master's pfds.
- *
- * We are including POLLERR here to do a READ event
- * this is because the read should fail and the
- * read function should handle it appropriately
- */
- if (pfds[i].revents & (POLLIN | POLLHUP | POLLERR)) {
- thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN,
- pfds[i].revents, i);
- }
- if (pfds[i].revents & POLLOUT)
- thread_process_io_helper(m, m->write[pfds[i].fd],
- POLLOUT, pfds[i].revents, i);
-
- /* if one of our file descriptors is garbage, remove the same
- * from
- * both pfds + update sizes and index */
- if (pfds[i].revents & POLLNVAL) {
- memmove(m->handler.pfds + i, m->handler.pfds + i + 1,
- (m->handler.pfdcount - i - 1)
- * sizeof(struct pollfd));
- m->handler.pfdcount--;
- m->handler.pfds[m->handler.pfdcount].fd = 0;
- m->handler.pfds[m->handler.pfdcount].events = 0;
-
- memmove(pfds + i, pfds + i + 1,
- (m->handler.copycount - i - 1)
- * sizeof(struct pollfd));
- m->handler.copycount--;
- m->handler.copy[m->handler.copycount].fd = 0;
- m->handler.copy[m->handler.copycount].events = 0;
-
- i--;
- }
- }
-}
-
-/* Add all timers that have popped to the ready list. */
-static unsigned int thread_process_timers(struct thread_master *m,
- struct timeval *timenow)
-{
- struct timeval prev = *timenow;
- bool displayed = false;
- struct thread *thread;
- unsigned int ready = 0;
-
- while ((thread = thread_timer_list_first(&m->timer))) {
- if (timercmp(timenow, &thread->u.sands, <))
- break;
- prev = thread->u.sands;
- prev.tv_sec += 4;
- /*
- * If the timer would have popped 4 seconds in the
- * past then we are in a situation where we are
- * really getting behind on handling of events.
- * Let's log it and do the right thing with it.
- */
- if (timercmp(timenow, &prev, >)) {
- atomic_fetch_add_explicit(
- &thread->hist->total_starv_warn, 1,
- memory_order_seq_cst);
- if (!displayed && !thread->ignore_timer_late) {
- flog_warn(
- EC_LIB_STARVE_THREAD,
- "Thread Starvation: %pTHD was scheduled to pop greater than 4s ago",
- thread);
- displayed = true;
- }
- }
-
- thread_timer_list_pop(&m->timer);
- thread->type = THREAD_READY;
- thread_list_add_tail(&m->ready, thread);
- ready++;
- }
-
- return ready;
-}
-
-/* process a list en masse, e.g. for event thread lists */
-static unsigned int thread_process(struct thread_list_head *list)
-{
- struct thread *thread;
- unsigned int ready = 0;
-
- while ((thread = thread_list_pop(list))) {
- thread->type = THREAD_READY;
- thread_list_add_tail(&thread->master->ready, thread);
- ready++;
- }
- return ready;
-}
-
-
-/* Fetch next ready thread. */
-struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
-{
- struct thread *thread = NULL;
- struct timeval now;
- struct timeval zerotime = {0, 0};
- struct timeval tv;
- struct timeval *tw = NULL;
- bool eintr_p = false;
- int num = 0;
-
- do {
- /* Handle signals if any */
- if (m->handle_signals)
- frr_sigevent_process();
-
- pthread_mutex_lock(&m->mtx);
-
- /* Process any pending cancellation requests */
- do_thread_cancel(m);
-
- /*
- * Attempt to flush ready queue before going into poll().
- * This is performance-critical. Think twice before modifying.
- */
- if ((thread = thread_list_pop(&m->ready))) {
- fetch = thread_run(m, thread, fetch);
- if (fetch->ref)
- *fetch->ref = NULL;
- pthread_mutex_unlock(&m->mtx);
- if (!m->ready_run_loop)
- GETRUSAGE(&m->last_getrusage);
- m->ready_run_loop = true;
- break;
- }
-
- m->ready_run_loop = false;
- /* otherwise, tick through scheduling sequence */
-
- /*
- * Post events to ready queue. This must come before the
- * following block since events should occur immediately
- */
- thread_process(&m->event);
-
- /*
- * If there are no tasks on the ready queue, we will poll()
- * until a timer expires or we receive I/O, whichever comes
- * first. The strategy for doing this is:
- *
- * - If there are events pending, set the poll() timeout to zero
- * - If there are no events pending, but there are timers
- * pending, set the timeout to the smallest remaining time on
- * any timer.
- * - If there are neither timers nor events pending, but there
- * are file descriptors pending, block indefinitely in poll()
- * - If nothing is pending, it's time for the application to die
- *
- * In every case except the last, we need to hit poll() at least
- * once per loop to avoid starvation by events
- */
- if (!thread_list_count(&m->ready))
- tw = thread_timer_wait(&m->timer, &tv);
-
- if (thread_list_count(&m->ready) ||
- (tw && !timercmp(tw, &zerotime, >)))
- tw = &zerotime;
-
- if (!tw && m->handler.pfdcount == 0) { /* die */
- pthread_mutex_unlock(&m->mtx);
- fetch = NULL;
- break;
- }
-
- /*
- * Copy pollfd array + # active pollfds in it. Not necessary to
- * copy the array size as this is fixed.
- */
- m->handler.copycount = m->handler.pfdcount;
- memcpy(m->handler.copy, m->handler.pfds,
- m->handler.copycount * sizeof(struct pollfd));
-
- pthread_mutex_unlock(&m->mtx);
- {
- eintr_p = false;
- num = fd_poll(m, tw, &eintr_p);
- }
- pthread_mutex_lock(&m->mtx);
-
- /* Handle any errors received in poll() */
- if (num < 0) {
- if (eintr_p) {
- pthread_mutex_unlock(&m->mtx);
- /* loop around to signal handler */
- continue;
- }
-
- /* else die */
- flog_err(EC_LIB_SYSTEM_CALL, "poll() error: %s",
- safe_strerror(errno));
- pthread_mutex_unlock(&m->mtx);
- fetch = NULL;
- break;
- }
-
- /* Post timers to ready queue. */
- monotime(&now);
- thread_process_timers(m, &now);
-
- /* Post I/O to ready queue. */
- if (num > 0)
- thread_process_io(m, num);
-
- pthread_mutex_unlock(&m->mtx);
-
- } while (!thread && m->spin);
-
- return fetch;
-}
-
-static unsigned long timeval_elapsed(struct timeval a, struct timeval b)
-{
- return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
- + (a.tv_usec - b.tv_usec));
-}
-
-unsigned long thread_consumed_time(RUSAGE_T *now, RUSAGE_T *start,
- unsigned long *cputime)
-{
-#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
-
-#ifdef __FreeBSD__
- /*
- * FreeBSD appears to have an issue when calling clock_gettime
- * with CLOCK_THREAD_CPUTIME_ID really close to each other
- * occassionally the now time will be before the start time.
- * This is not good and FRR is ending up with CPU HOG's
- * when the subtraction wraps to very large numbers
- *
- * What we are going to do here is cheat a little bit
- * and notice that this is a problem and just correct
- * it so that it is impossible to happen
- */
- if (start->cpu.tv_sec == now->cpu.tv_sec &&
- start->cpu.tv_nsec > now->cpu.tv_nsec)
- now->cpu.tv_nsec = start->cpu.tv_nsec + 1;
- else if (start->cpu.tv_sec > now->cpu.tv_sec) {
- now->cpu.tv_sec = start->cpu.tv_sec;
- now->cpu.tv_nsec = start->cpu.tv_nsec + 1;
- }
-#endif
- *cputime = (now->cpu.tv_sec - start->cpu.tv_sec) * TIMER_SECOND_MICRO
- + (now->cpu.tv_nsec - start->cpu.tv_nsec) / 1000;
-#else
- /* This is 'user + sys' time. */
- *cputime = timeval_elapsed(now->cpu.ru_utime, start->cpu.ru_utime)
- + timeval_elapsed(now->cpu.ru_stime, start->cpu.ru_stime);
-#endif
- return timeval_elapsed(now->real, start->real);
-}
-
-/* We should aim to yield after yield milliseconds, which defaults
- to THREAD_YIELD_TIME_SLOT .
- Note: we are using real (wall clock) time for this calculation.
- It could be argued that CPU time may make more sense in certain
- contexts. The things to consider are whether the thread may have
- blocked (in which case wall time increases, but CPU time does not),
- or whether the system is heavily loaded with other processes competing
- for CPU time. On balance, wall clock time seems to make sense.
- Plus it has the added benefit that gettimeofday should be faster
- than calling getrusage. */
-int thread_should_yield(struct thread *thread)
-{
- int result;
- frr_with_mutex (&thread->mtx) {
- result = monotime_since(&thread->real, NULL)
- > (int64_t)thread->yield;
- }
- return result;
-}
-
-void thread_set_yield_time(struct thread *thread, unsigned long yield_time)
-{
- frr_with_mutex (&thread->mtx) {
- thread->yield = yield_time;
- }
-}
-
-void thread_getrusage(RUSAGE_T *r)
-{
- monotime(&r->real);
- if (!cputime_enabled) {
- memset(&r->cpu, 0, sizeof(r->cpu));
- return;
- }
-
-#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
- /* not currently implemented in Linux's vDSO, but maybe at some point
- * in the future?
- */
- clock_gettime(CLOCK_THREAD_CPUTIME_ID, &r->cpu);
-#else /* !HAVE_CLOCK_THREAD_CPUTIME_ID */
-#if defined RUSAGE_THREAD
-#define FRR_RUSAGE RUSAGE_THREAD
-#else
-#define FRR_RUSAGE RUSAGE_SELF
-#endif
- getrusage(FRR_RUSAGE, &(r->cpu));
-#endif
-}
-
-/*
- * Call a thread.
- *
- * This function will atomically update the thread's usage history. At present
- * this is the only spot where usage history is written. Nevertheless the code
- * has been written such that the introduction of writers in the future should
- * not need to update it provided the writers atomically perform only the
- * operations done here, i.e. updating the total and maximum times. In
- * particular, the maximum real and cpu times must be monotonically increasing
- * or this code is not correct.
- */
-void thread_call(struct thread *thread)
-{
- RUSAGE_T before, after;
-
- /* if the thread being called is the CLI, it may change cputime_enabled
- * ("service cputime-stats" command), which can result in nonsensical
- * and very confusing warnings
- */
- bool cputime_enabled_here = cputime_enabled;
-
- if (thread->master->ready_run_loop)
- before = thread->master->last_getrusage;
- else
- GETRUSAGE(&before);
-
- thread->real = before.real;
-
- frrtrace(9, frr_libfrr, thread_call, thread->master,
- thread->xref->funcname, thread->xref->xref.file,
- thread->xref->xref.line, NULL, thread->u.fd,
- thread->u.val, thread->arg, thread->u.sands.tv_sec);
-
- pthread_setspecific(thread_current, thread);
- (*thread->func)(thread);
- pthread_setspecific(thread_current, NULL);
-
- GETRUSAGE(&after);
- thread->master->last_getrusage = after;
-
- unsigned long walltime, cputime;
- unsigned long exp;
-
- walltime = thread_consumed_time(&after, &before, &cputime);
-
- /* update walltime */
- atomic_fetch_add_explicit(&thread->hist->real.total, walltime,
- memory_order_seq_cst);
- exp = atomic_load_explicit(&thread->hist->real.max,
- memory_order_seq_cst);
- while (exp < walltime
- && !atomic_compare_exchange_weak_explicit(
- &thread->hist->real.max, &exp, walltime,
- memory_order_seq_cst, memory_order_seq_cst))
- ;
-
- if (cputime_enabled_here && cputime_enabled) {
- /* update cputime */
- atomic_fetch_add_explicit(&thread->hist->cpu.total, cputime,
- memory_order_seq_cst);
- exp = atomic_load_explicit(&thread->hist->cpu.max,
- memory_order_seq_cst);
- while (exp < cputime
- && !atomic_compare_exchange_weak_explicit(
- &thread->hist->cpu.max, &exp, cputime,
- memory_order_seq_cst, memory_order_seq_cst))
- ;
- }
-
- atomic_fetch_add_explicit(&thread->hist->total_calls, 1,
- memory_order_seq_cst);
- atomic_fetch_or_explicit(&thread->hist->types, 1 << thread->add_type,
- memory_order_seq_cst);
-
- if (cputime_enabled_here && cputime_enabled && cputime_threshold
- && cputime > cputime_threshold) {
- /*
- * We have a CPU Hog on our hands. The time FRR has spent
- * doing actual work (not sleeping) is greater than 5 seconds.
- * Whinge about it now, so we're aware this is yet another task
- * to fix.
- */
- atomic_fetch_add_explicit(&thread->hist->total_cpu_warn,
- 1, memory_order_seq_cst);
- flog_warn(
- EC_LIB_SLOW_THREAD_CPU,
- "CPU HOG: task %s (%lx) ran for %lums (cpu time %lums)",
- thread->xref->funcname, (unsigned long)thread->func,
- walltime / 1000, cputime / 1000);
-
- } else if (walltime_threshold && walltime > walltime_threshold) {
- /*
- * The runtime for a task is greater than 5 seconds, but the
- * cpu time is under 5 seconds. Let's whine about this because
- * this could imply some sort of scheduling issue.
- */
- atomic_fetch_add_explicit(&thread->hist->total_wall_warn,
- 1, memory_order_seq_cst);
- flog_warn(
- EC_LIB_SLOW_THREAD_WALL,
- "STARVATION: task %s (%lx) ran for %lums (cpu time %lums)",
- thread->xref->funcname, (unsigned long)thread->func,
- walltime / 1000, cputime / 1000);
- }
-}
-
-/* Execute thread */
-void _thread_execute(const struct xref_threadsched *xref,
- struct thread_master *m, void (*func)(struct thread *),
- void *arg, int val)
-{
- struct thread *thread;
-
- /* Get or allocate new thread to execute. */
- frr_with_mutex (&m->mtx) {
- thread = thread_get(m, THREAD_EVENT, func, arg, xref);
-
- /* Set its event value. */
- frr_with_mutex (&thread->mtx) {
- thread->add_type = THREAD_EXECUTE;
- thread->u.val = val;
- thread->ref = &thread;
- }
- }
-
- /* Execute thread doing all accounting. */
- thread_call(thread);
-
- /* Give back or free thread. */
- thread_add_unuse(m, thread);
-}
-
-/* Debug signal mask - if 'sigs' is NULL, use current effective mask. */
-void debug_signals(const sigset_t *sigs)
-{
- int i, found;
- sigset_t tmpsigs;
- char buf[300];
-
- /*
- * We're only looking at the non-realtime signals here, so we need
- * some limit value. Platform differences mean at some point we just
- * need to pick a reasonable value.
- */
-#if defined SIGRTMIN
-# define LAST_SIGNAL SIGRTMIN
-#else
-# define LAST_SIGNAL 32
-#endif
-
-
- if (sigs == NULL) {
- sigemptyset(&tmpsigs);
- pthread_sigmask(SIG_BLOCK, NULL, &tmpsigs);
- sigs = &tmpsigs;
- }
-
- found = 0;
- buf[0] = '\0';
-
- for (i = 0; i < LAST_SIGNAL; i++) {
- char tmp[20];
-
- if (sigismember(sigs, i) > 0) {
- if (found > 0)
- strlcat(buf, ",", sizeof(buf));
- snprintf(tmp, sizeof(tmp), "%d", i);
- strlcat(buf, tmp, sizeof(buf));
- found++;
- }
- }
-
- if (found == 0)
- snprintf(buf, sizeof(buf), "<none>");
-
- zlog_debug("%s: %s", __func__, buf);
-}
-
-static ssize_t printfrr_thread_dbg(struct fbuf *buf, struct printfrr_eargs *ea,
- const struct thread *thread)
-{
- static const char * const types[] = {
- [THREAD_READ] = "read",
- [THREAD_WRITE] = "write",
- [THREAD_TIMER] = "timer",
- [THREAD_EVENT] = "event",
- [THREAD_READY] = "ready",
- [THREAD_UNUSED] = "unused",
- [THREAD_EXECUTE] = "exec",
- };
- ssize_t rv = 0;
- char info[16] = "";
-
- if (!thread)
- return bputs(buf, "{(thread *)NULL}");
-
- rv += bprintfrr(buf, "{(thread *)%p arg=%p", thread, thread->arg);
-
- if (thread->type < array_size(types) && types[thread->type])
- rv += bprintfrr(buf, " %-6s", types[thread->type]);
- else
- rv += bprintfrr(buf, " INVALID(%u)", thread->type);
-
- switch (thread->type) {
- case THREAD_READ:
- case THREAD_WRITE:
- snprintfrr(info, sizeof(info), "fd=%d", thread->u.fd);
- break;
-
- case THREAD_TIMER:
- snprintfrr(info, sizeof(info), "r=%pTVMud", &thread->u.sands);
- break;
- }
-
- rv += bprintfrr(buf, " %-12s %s() %s from %s:%d}", info,
- thread->xref->funcname, thread->xref->dest,
- thread->xref->xref.file, thread->xref->xref.line);
- return rv;
-}
-
-printfrr_ext_autoreg_p("TH", printfrr_thread);
-static ssize_t printfrr_thread(struct fbuf *buf, struct printfrr_eargs *ea,
- const void *ptr)
-{
- const struct thread *thread = ptr;
- struct timespec remain = {};
-
- if (ea->fmt[0] == 'D') {
- ea->fmt++;
- return printfrr_thread_dbg(buf, ea, thread);
- }
-
- if (!thread) {
- /* need to jump over time formatting flag characters in the
- * input format string, i.e. adjust ea->fmt!
- */
- printfrr_time(buf, ea, &remain,
- TIMEFMT_TIMER_DEADLINE | TIMEFMT_SKIP);
- return bputch(buf, '-');
- }
-
- TIMEVAL_TO_TIMESPEC(&thread->u.sands, &remain);
- return printfrr_time(buf, ea, &remain, TIMEFMT_TIMER_DEADLINE);
-}
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* Thread management routine header.
- * Copyright (C) 1998 Kunihiro Ishiguro
- */
-
-#ifndef _ZEBRA_THREAD_H
-#define _ZEBRA_THREAD_H
-
-#include <zebra.h>
-#include <pthread.h>
-#include <poll.h>
-#include "monotime.h"
-#include "frratomic.h"
-#include "typesafe.h"
-#include "xref.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern bool cputime_enabled;
-extern unsigned long cputime_threshold;
-/* capturing wallclock time is always enabled since it is fast (reading
- * hardware TSC w/o syscalls)
- */
-extern unsigned long walltime_threshold;
-
-struct rusage_t {
-#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
- struct timespec cpu;
-#else
- struct rusage cpu;
-#endif
- struct timeval real;
-};
-#define RUSAGE_T struct rusage_t
-
-#define GETRUSAGE(X) thread_getrusage(X)
-
-PREDECL_LIST(thread_list);
-PREDECL_HEAP(thread_timer_list);
-
-struct fd_handler {
- /* number of pfd that fit in the allocated space of pfds. This is a
- * constant and is the same for both pfds and copy.
- */
- nfds_t pfdsize;
-
- /* file descriptors to monitor for i/o */
- struct pollfd *pfds;
- /* number of pollfds stored in pfds */
- nfds_t pfdcount;
-
- /* chunk used for temp copy of pollfds */
- struct pollfd *copy;
- /* number of pollfds stored in copy */
- nfds_t copycount;
-};
-
-struct xref_threadsched {
- struct xref xref;
-
- const char *funcname;
- const char *dest;
- uint32_t thread_type;
-};
-
-/* Master of the theads. */
-struct thread_master {
- char *name;
-
- struct thread **read;
- struct thread **write;
- struct thread_timer_list_head timer;
- struct thread_list_head event, ready, unuse;
- struct list *cancel_req;
- bool canceled;
- pthread_cond_t cancel_cond;
- struct hash *cpu_record;
- int io_pipe[2];
- int fd_limit;
- struct fd_handler handler;
- unsigned long alloc;
- long selectpoll_timeout;
- bool spin;
- bool handle_signals;
- pthread_mutex_t mtx;
- pthread_t owner;
-
- bool ready_run_loop;
- RUSAGE_T last_getrusage;
-};
-
-/* Thread itself. */
-struct thread {
- uint8_t type; /* thread type */
- uint8_t add_type; /* thread type */
- struct thread_list_item threaditem;
- struct thread_timer_list_item timeritem;
- struct thread **ref; /* external reference (if given) */
- struct thread_master *master; /* pointer to the struct thread_master */
- void (*func)(struct thread *); /* event function */
- void *arg; /* event argument */
- union {
- int val; /* second argument of the event. */
- int fd; /* file descriptor in case of r/w */
- struct timeval sands; /* rest of time sands value. */
- } u;
- struct timeval real;
- struct cpu_thread_history *hist; /* cache pointer to cpu_history */
- unsigned long yield; /* yield time in microseconds */
- const struct xref_threadsched *xref; /* origin location */
- pthread_mutex_t mtx; /* mutex for thread.c functions */
- bool ignore_timer_late;
-};
-
-#ifdef _FRR_ATTRIBUTE_PRINTFRR
-#pragma FRR printfrr_ext "%pTH" (struct thread *)
-#endif
-
-struct cpu_thread_history {
- void (*func)(struct thread *);
- atomic_size_t total_cpu_warn;
- atomic_size_t total_wall_warn;
- atomic_size_t total_starv_warn;
- atomic_size_t total_calls;
- atomic_size_t total_active;
- struct time_stats {
- atomic_size_t total, max;
- } real;
- struct time_stats cpu;
- atomic_uint_fast32_t types;
- const char *funcname;
-};
-
-/* Struct timeval's tv_usec one second value. */
-#define TIMER_SECOND_MICRO 1000000L
-
-/* Thread types. */
-#define THREAD_READ 0
-#define THREAD_WRITE 1
-#define THREAD_TIMER 2
-#define THREAD_EVENT 3
-#define THREAD_READY 4
-#define THREAD_UNUSED 5
-#define THREAD_EXECUTE 6
-
-/* Thread yield time. */
-#define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
-
-#define THREAD_TIMER_STRLEN 12
-
-/* Macros. */
-#define THREAD_ARG(X) ((X)->arg)
-#define THREAD_FD(X) ((X)->u.fd)
-#define THREAD_VAL(X) ((X)->u.val)
-
-/*
- * Please consider this macro deprecated, and do not use it in new code.
- */
-#define THREAD_OFF(thread) \
- do { \
- if ((thread)) \
- thread_cancel(&(thread)); \
- } while (0)
-
-/*
- * Macro wrappers to generate xrefs for all thread add calls. Includes
- * file/line/function info for debugging/tracing.
- */
-#include "lib/xref.h"
-
-#define _xref_t_a(addfn, type, m, f, a, v, t) \
- ({ \
- static const struct xref_threadsched _xref \
- __attribute__((used)) = { \
- .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
- .funcname = #f, \
- .dest = #t, \
- .thread_type = THREAD_ ## type, \
- }; \
- XREF_LINK(_xref.xref); \
- _thread_add_ ## addfn(&_xref, m, f, a, v, t); \
- }) \
- /* end */
-
-#define thread_add_read(m,f,a,v,t) _xref_t_a(read_write, READ, m,f,a,v,t)
-#define thread_add_write(m,f,a,v,t) _xref_t_a(read_write, WRITE, m,f,a,v,t)
-#define thread_add_timer(m,f,a,v,t) _xref_t_a(timer, TIMER, m,f,a,v,t)
-#define thread_add_timer_msec(m,f,a,v,t) _xref_t_a(timer_msec, TIMER, m,f,a,v,t)
-#define thread_add_timer_tv(m,f,a,v,t) _xref_t_a(timer_tv, TIMER, m,f,a,v,t)
-#define thread_add_event(m,f,a,v,t) _xref_t_a(event, EVENT, m,f,a,v,t)
-
-#define thread_execute(m,f,a,v) \
- ({ \
- static const struct xref_threadsched _xref \
- __attribute__((used)) = { \
- .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
- .funcname = #f, \
- .dest = NULL, \
- .thread_type = THREAD_EXECUTE, \
- }; \
- XREF_LINK(_xref.xref); \
- _thread_execute(&_xref, m, f, a, v); \
- }) /* end */
-
-/* Prototypes. */
-extern struct thread_master *thread_master_create(const char *);
-void thread_master_set_name(struct thread_master *master, const char *name);
-extern void thread_master_free(struct thread_master *);
-extern void thread_master_free_unused(struct thread_master *);
-
-extern void _thread_add_read_write(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*fn)(struct thread *), void *arg,
- int fd, struct thread **tref);
-
-extern void _thread_add_timer(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*fn)(struct thread *), void *arg, long t,
- struct thread **tref);
-
-extern void _thread_add_timer_msec(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*fn)(struct thread *), void *arg,
- long t, struct thread **tref);
-
-extern void _thread_add_timer_tv(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*fn)(struct thread *), void *arg,
- struct timeval *tv, struct thread **tref);
-
-extern void _thread_add_event(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*fn)(struct thread *), void *arg, int val,
- struct thread **tref);
-
-extern void _thread_execute(const struct xref_threadsched *xref,
- struct thread_master *master,
- void (*fn)(struct thread *), void *arg, int val);
-
-extern void thread_cancel(struct thread **event);
-extern void thread_cancel_async(struct thread_master *, struct thread **,
- void *);
-/* Cancel ready tasks with an arg matching 'arg' */
-extern void thread_cancel_event_ready(struct thread_master *m, void *arg);
-/* Cancel all tasks with an arg matching 'arg', including timers and io */
-extern void thread_cancel_event(struct thread_master *m, void *arg);
-extern struct thread *thread_fetch(struct thread_master *, struct thread *);
-extern void thread_call(struct thread *);
-extern unsigned long thread_timer_remain_second(struct thread *);
-extern struct timeval thread_timer_remain(struct thread *);
-extern unsigned long thread_timer_remain_msec(struct thread *);
-extern int thread_should_yield(struct thread *);
-/* set yield time for thread */
-extern void thread_set_yield_time(struct thread *, unsigned long);
-
-/* Internal libfrr exports */
-extern void thread_getrusage(RUSAGE_T *);
-extern void thread_cmd_init(void);
-
-/* Returns elapsed real (wall clock) time. */
-extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
- unsigned long *cpu_time_elapsed);
-
-/* only for use in logging functions! */
-extern pthread_key_t thread_current;
-extern char *thread_timer_to_hhmmss(char *buf, int buf_size,
- struct thread *t_timer);
-
-static inline bool thread_is_scheduled(struct thread *thread)
-{
- if (thread)
- return true;
-
- return false;
-}
-
-/* Debug signal mask */
-void debug_signals(const sigset_t *sigs);
-
-static inline void thread_ignore_late_timer(struct thread *thread)
-{
- thread->ignore_timer_late = true;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZEBRA_THREAD_H */
{
struct hash *vrf_hash = bmap;
- if (vrf_hash == NULL)
- return;
-
- hash_clean(vrf_hash, vrf_hash_bitmap_free);
- hash_free(vrf_hash);
+ hash_clean_and_free(&vrf_hash, vrf_hash_bitmap_free);
}
void vrf_bitmap_set(vrf_bitmap_t bmap, vrf_id_t vrf_id)
#include <stdio.h>
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "command.h"
#include "sockunion.h"
int sock;
bool vtysh;
- struct thread *t_accept;
+ struct event *t_accept;
};
DECLARE_DLIST(vtyservs, struct vty_serv, itm);
GETRUSAGE(&after);
- walltime = thread_consumed_time(&after, &before, &cputime);
+ walltime = event_consumed_time(&after, &before, &cputime);
if (cputime_enabled_here && cputime_enabled && cputime_threshold
&& cputime > cputime_threshold)
}
/* Read data via vty socket. */
-static void vty_read(struct thread *thread)
+static void vty_read(struct event *thread)
{
int i;
int nbytes;
unsigned char buf[VTY_READ_BUFSIZ];
- struct vty *vty = THREAD_ARG(thread);
+ struct vty *vty = EVENT_ARG(thread);
/* Read raw data from socket */
if ((nbytes = read(vty->fd, buf, VTY_READ_BUFSIZ)) <= 0) {
}
/* Flush buffer to the vty. */
-static void vty_flush(struct thread *thread)
+static void vty_flush(struct event *thread)
{
int erase;
buffer_status_t flushrc;
- struct vty *vty = THREAD_ARG(thread);
+ struct vty *vty = EVENT_ARG(thread);
/* Tempolary disable read thread. */
if (vty->lines == 0)
- THREAD_OFF(vty->t_read);
+ EVENT_OFF(vty->t_read);
/* Function execution continue. */
erase = ((vty->status == VTY_MORE || vty->status == VTY_MORELINE));
if (!stdio_vty)
return;
- THREAD_OFF(stdio_vty->t_write);
- THREAD_OFF(stdio_vty->t_read);
- THREAD_OFF(stdio_vty->t_timeout);
+ EVENT_OFF(stdio_vty->t_write);
+ EVENT_OFF(stdio_vty->t_read);
+ EVENT_OFF(stdio_vty->t_timeout);
if (stdio_termios)
tcsetattr(0, TCSANOW, &stdio_orig_termios);
}
/* Accept connection from the network. */
-static void vty_accept(struct thread *thread)
+static void vty_accept(struct event *thread)
{
- struct vty_serv *vtyserv = THREAD_ARG(thread);
+ struct vty_serv *vtyserv = EVENT_ARG(thread);
int vty_sock;
union sockunion su;
int ret;
/* #define VTYSH_DEBUG 1 */
-static void vtysh_accept(struct thread *thread)
+static void vtysh_accept(struct event *thread)
{
- struct vty_serv *vtyserv = THREAD_ARG(thread);
+ struct vty_serv *vtyserv = EVENT_ARG(thread);
int accept_sock = vtyserv->sock;
int sock;
int client_len;
vty->pass_fd = fd;
}
-static void vtysh_read(struct thread *thread)
+static void vtysh_read(struct event *thread)
{
int ret;
int sock;
unsigned char *p;
uint8_t header[4] = {0, 0, 0, 0};
- sock = THREAD_FD(thread);
- vty = THREAD_ARG(thread);
+ sock = EVENT_FD(thread);
+ vty = EVENT_ARG(thread);
if ((nbytes = read(sock, buf, VTY_READ_BUFSIZ)) <= 0) {
if (nbytes < 0) {
vty_event(VTYSH_READ, vty);
}
-static void vtysh_write(struct thread *thread)
+static void vtysh_write(struct event *thread)
{
- struct vty *vty = THREAD_ARG(thread);
+ struct vty *vty = EVENT_ARG(thread);
vtysh_flush(vty);
}
vty_config_exit(vty);
/* Cancel threads.*/
- THREAD_OFF(vty->t_read);
- THREAD_OFF(vty->t_write);
- THREAD_OFF(vty->t_timeout);
+ EVENT_OFF(vty->t_read);
+ EVENT_OFF(vty->t_write);
+ EVENT_OFF(vty->t_timeout);
if (vty->pass_fd != -1) {
close(vty->pass_fd);
}
/* When time out occur output message then close connection. */
-static void vty_timeout(struct thread *thread)
+static void vty_timeout(struct event *thread)
{
struct vty *vty;
- vty = THREAD_ARG(thread);
+ vty = EVENT_ARG(thread);
vty->v_timeout = 0;
/* Clear buffer*/
}
/* Master of the threads. */
-static struct thread_master *vty_master;
+static struct event_loop *vty_master;
static void vty_event_serv(enum vty_event event, struct vty_serv *vty_serv)
{
switch (event) {
case VTY_SERV:
- thread_add_read(vty_master, vty_accept, vty_serv,
- vty_serv->sock, &vty_serv->t_accept);
+ event_add_read(vty_master, vty_accept, vty_serv, vty_serv->sock,
+ &vty_serv->t_accept);
break;
#ifdef VTYSH
case VTYSH_SERV:
- thread_add_read(vty_master, vtysh_accept, vty_serv,
- vty_serv->sock, &vty_serv->t_accept);
+ event_add_read(vty_master, vtysh_accept, vty_serv,
+ vty_serv->sock, &vty_serv->t_accept);
break;
#endif /* VTYSH */
case VTY_READ:
switch (event) {
#ifdef VTYSH
case VTYSH_READ:
- thread_add_read(vty_master, vtysh_read, vty, vty->fd,
- &vty->t_read);
+ event_add_read(vty_master, vtysh_read, vty, vty->fd,
+ &vty->t_read);
break;
case VTYSH_WRITE:
- thread_add_write(vty_master, vtysh_write, vty, vty->wfd,
- &vty->t_write);
+ event_add_write(vty_master, vtysh_write, vty, vty->wfd,
+ &vty->t_write);
break;
#endif /* VTYSH */
case VTY_READ:
- thread_add_read(vty_master, vty_read, vty, vty->fd,
- &vty->t_read);
+ event_add_read(vty_master, vty_read, vty, vty->fd,
+ &vty->t_read);
/* Time out treatment. */
if (vty->v_timeout) {
- THREAD_OFF(vty->t_timeout);
- thread_add_timer(vty_master, vty_timeout, vty,
- vty->v_timeout, &vty->t_timeout);
+ EVENT_OFF(vty->t_timeout);
+ event_add_timer(vty_master, vty_timeout, vty,
+ vty->v_timeout, &vty->t_timeout);
}
break;
case VTY_WRITE:
- thread_add_write(vty_master, vty_flush, vty, vty->wfd,
- &vty->t_write);
+ event_add_write(vty_master, vty_flush, vty, vty->wfd,
+ &vty->t_write);
break;
case VTY_TIMEOUT_RESET:
- THREAD_OFF(vty->t_timeout);
+ EVENT_OFF(vty->t_timeout);
if (vty->v_timeout)
- thread_add_timer(vty_master, vty_timeout, vty,
- vty->v_timeout, &vty->t_timeout);
+ event_add_timer(vty_master, vty_timeout, vty,
+ vty->v_timeout, &vty->t_timeout);
break;
case VTY_SERV:
case VTYSH_SERV:
}
/* Install vty's own commands like `who' command. */
-void vty_init(struct thread_master *master_thread, bool do_command_logging)
+void vty_init(struct event_loop *master_thread, bool do_command_logging)
{
/* For further configuration read, preserve current directory. */
vty_save_cwd();
vtys_init(vtysh_sessions);
while ((vtyserv = vtyservs_pop(vty_servs))) {
- THREAD_OFF(vtyserv->t_accept);
+ EVENT_OFF(vtyserv->t_accept);
close(vtyserv->sock);
XFREE(MTYPE_VTY_SERV, vtyserv);
}
#include <regex.h>
#endif /* HAVE_LIBPCRE2_POSIX */
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "sockunion.h"
#include "qobj.h"
size_t pending_cmds_bufpos;
/* Confirmed-commit timeout and rollback configuration. */
- struct thread *t_confirmed_commit_timeout;
+ struct event *t_confirmed_commit_timeout;
struct nb_config *confirmed_commit_rollback;
/* qobj object ID (replacement for "index") */
int lines;
/* Read and write thread. */
- struct thread *t_read;
- struct thread *t_write;
+ struct event *t_read;
+ struct event *t_write;
/* Timeout seconds and thread. */
unsigned long v_timeout;
- struct thread *t_timeout;
+ struct event *t_timeout;
/* What address is this vty comming from. */
char address[SU_ADDRSTRLEN];
extern struct nb_config *vty_mgmt_candidate_config;
/* Prototypes. */
-extern void vty_init(struct thread_master *, bool do_command_logging);
+extern void vty_init(struct event_loop *m, bool do_command_logging);
extern void vty_init_vtysh(void);
extern void vty_terminate(void);
extern void vty_reset(void);
*/
#include "zebra.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "wheel.h"
#include "log.h"
static int debug_timer_wheel = 0;
-static void wheel_timer_thread(struct thread *t);
+static void wheel_timer_thread(struct event *t);
-static void wheel_timer_thread_helper(struct thread *t)
+static void wheel_timer_thread_helper(struct event *t)
{
struct listnode *node, *nextnode;
unsigned long long curr_slot;
struct timer_wheel *wheel;
void *data;
- wheel = THREAD_ARG(t);
+ wheel = EVENT_ARG(t);
wheel->curr_slot += wheel->slots_to_skip;
slots_to_skip++;
wheel->slots_to_skip = slots_to_skip;
- thread_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
- wheel->nexttime * slots_to_skip, &wheel->timer);
+ event_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
+ wheel->nexttime * slots_to_skip, &wheel->timer);
}
-static void wheel_timer_thread(struct thread *t)
+static void wheel_timer_thread(struct event *t)
{
struct timer_wheel *wheel;
- wheel = THREAD_ARG(t);
+ wheel = EVENT_ARG(t);
- thread_execute(wheel->master, wheel_timer_thread_helper, wheel, 0);
+ event_execute(wheel->master, wheel_timer_thread_helper, wheel, 0);
}
-struct timer_wheel *wheel_init(struct thread_master *master, int period,
- size_t slots, unsigned int (*slot_key)(const void *),
- void (*slot_run)(void *),
- const char *run_name)
+struct timer_wheel *wheel_init(struct event_loop *master, int period,
+ size_t slots,
+ unsigned int (*slot_key)(const void *),
+ void (*slot_run)(void *), const char *run_name)
{
struct timer_wheel *wheel;
size_t i;
for (i = 0; i < slots; i++)
wheel->wheel_slot_lists[i] = list_new();
- thread_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
- wheel->nexttime, &wheel->timer);
+ event_add_timer_msec(wheel->master, wheel_timer_thread, wheel,
+ wheel->nexttime, &wheel->timer);
return wheel;
}
list_delete(&wheel->wheel_slot_lists[i]);
}
- THREAD_OFF(wheel->timer);
+ EVENT_OFF(wheel->timer);
XFREE(MTYPE_TIMER_WHEEL_LIST, wheel->wheel_slot_lists);
XFREE(MTYPE_TIMER_WHEEL, wheel->name);
XFREE(MTYPE_TIMER_WHEEL, wheel);
struct timer_wheel {
char *name;
- struct thread_master *master;
+ struct event_loop *master;
int slots;
long long curr_slot;
unsigned int period;
unsigned int slots_to_skip;
struct list **wheel_slot_lists;
- struct thread *timer;
+ struct event *timer;
/*
* Key to determine what slot the item belongs in
*/
* and cause significant amount of time handling thread events instead
* of running your code.
*/
-struct timer_wheel *wheel_init(struct thread_master *master, int period,
+struct timer_wheel *wheel_init(struct event_loop *master, int period,
size_t slots,
unsigned int (*slot_key)(const void *),
void (*slot_run)(void *), const char *run_name);
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "workqueue.h"
#include "linklist.h"
}
/* create new work queue */
-struct work_queue *work_queue_new(struct thread_master *m,
- const char *queue_name)
+struct work_queue *work_queue_new(struct event_loop *m, const char *queue_name)
{
struct work_queue *new;
/* Default values, can be overridden by caller */
new->spec.hold = WORK_QUEUE_DEFAULT_HOLD;
- new->spec.yield = THREAD_YIELD_TIME_SLOT;
+ new->spec.yield = EVENT_YIELD_TIME_SLOT;
new->spec.retry = WORK_QUEUE_DEFAULT_RETRY;
return new;
{
struct work_queue *wq = *wqp;
- THREAD_OFF(wq->thread);
+ EVENT_OFF(wq->thread);
while (!work_queue_empty(wq)) {
struct work_queue_item *item = work_queue_last_item(wq);
bool work_queue_is_scheduled(struct work_queue *wq)
{
- return thread_is_scheduled(wq->thread);
+ return event_is_scheduled(wq->thread);
}
static int work_queue_schedule(struct work_queue *wq, unsigned int delay)
{
/* if appropriate, schedule work queue thread */
if (CHECK_FLAG(wq->flags, WQ_UNPLUGGED) &&
- !thread_is_scheduled(wq->thread) && !work_queue_empty(wq)) {
+ !event_is_scheduled(wq->thread) && !work_queue_empty(wq)) {
/* Schedule timer if there's a delay, otherwise just schedule
* as an 'event'
*/
if (delay > 0) {
- thread_add_timer_msec(wq->master, work_queue_run, wq,
- delay, &wq->thread);
- thread_ignore_late_timer(wq->thread);
+ event_add_timer_msec(wq->master, work_queue_run, wq,
+ delay, &wq->thread);
+ event_ignore_late_timer(wq->thread);
} else
- thread_add_event(wq->master, work_queue_run, wq, 0,
- &wq->thread);
+ event_add_event(wq->master, work_queue_run, wq, 0,
+ &wq->thread);
/* set thread yield time, if needed */
- if (thread_is_scheduled(wq->thread) &&
- wq->spec.yield != THREAD_YIELD_TIME_SLOT)
- thread_set_yield_time(wq->thread, wq->spec.yield);
+ if (event_is_scheduled(wq->thread) &&
+ wq->spec.yield != EVENT_YIELD_TIME_SLOT)
+ event_set_yield_time(wq->thread, wq->spec.yield);
return 1;
} else
return 0;
*/
void work_queue_plug(struct work_queue *wq)
{
- THREAD_OFF(wq->thread);
+ EVENT_OFF(wq->thread);
UNSET_FLAG(wq->flags, WQ_UNPLUGGED);
}
* will reschedule itself if required,
* otherwise work_queue_item_add
*/
-void work_queue_run(struct thread *thread)
+void work_queue_run(struct event *thread)
{
struct work_queue *wq;
struct work_queue_item *item, *titem;
unsigned int cycles = 0;
char yielded = 0;
- wq = THREAD_ARG(thread);
+ wq = EVENT_ARG(thread);
assert(wq);
cycles++;
/* test if we should yield */
- if (!(cycles % wq->cycles.granularity)
- && thread_should_yield(thread)) {
+ if (!(cycles % wq->cycles.granularity) &&
+ event_should_yield(thread)) {
yielded = 1;
goto stats;
}
/* Everything but the specification struct is private
* the following may be read
*/
- struct thread_master *master; /* thread master */
- struct thread *thread; /* thread, if one is active */
+ struct event_loop *master; /* thread master */
+ struct event *thread; /* thread, if one is active */
char *name; /* work queue name */
/* Specification for this work queue.
* user must fill in the spec of the returned work queue before adding
* anything to it
*/
-extern struct work_queue *work_queue_new(struct thread_master *m,
+extern struct work_queue *work_queue_new(struct event_loop *m,
const char *queue_name);
/* destroy work queue */
bool work_queue_is_scheduled(struct work_queue *wq);
/* Helpers, exported for thread.c and command.c */
-extern void work_queue_run(struct thread *thread);
+extern void work_queue_run(struct event *thread);
extern void workqueue_cmd_init(void);
enum xref_type {
XREFT_NONE = 0,
- XREFT_THREADSCHED = 0x100,
+ XREFT_EVENTSCHED = 0x100,
XREFT_LOGMSG = 0x200,
XREFT_ASSERT = 0x280,
#endif
#ifdef HAVE_SYSREPO
sr_subscription_ctx_t *sr_subscription;
- struct thread *sr_thread;
+ struct event *sr_thread;
#endif
};
RB_HEAD(yang_modules, yang_module);
#include "vrf_int.h"
#include "if.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "zclient.h"
#include "memory.h"
#include "table.h"
static int zclient_debug;
/* Allocate zclient structure. */
-struct zclient *zclient_new(struct thread_master *master,
+struct zclient *zclient_new(struct event_loop *master,
struct zclient_options *opt,
zclient_handler *const *handlers, size_t n_handlers)
{
zlog_debug("zclient %p stopped", zclient);
/* Stop threads. */
- THREAD_OFF(zclient->t_read);
- THREAD_OFF(zclient->t_connect);
- THREAD_OFF(zclient->t_write);
+ EVENT_OFF(zclient->t_read);
+ EVENT_OFF(zclient->t_connect);
+ EVENT_OFF(zclient->t_write);
/* Reset streams. */
stream_reset(zclient->ibuf);
return ZCLIENT_SEND_FAILURE;
}
-static void zclient_flush_data(struct thread *thread)
+static void zclient_flush_data(struct event *thread)
{
- struct zclient *zclient = THREAD_ARG(thread);
+ struct zclient *zclient = EVENT_ARG(thread);
zclient->t_write = NULL;
if (zclient->sock < 0)
return;
case BUFFER_PENDING:
zclient->t_write = NULL;
- thread_add_write(zclient->master, zclient_flush_data, zclient,
- zclient->sock, &zclient->t_write);
+ event_add_write(zclient->master, zclient_flush_data, zclient,
+ zclient->sock, &zclient->t_write);
break;
case BUFFER_EMPTY:
if (zclient->zebra_buffer_write_ready)
__func__, zclient->sock);
return zclient_failed(zclient);
case BUFFER_EMPTY:
- THREAD_OFF(zclient->t_write);
+ EVENT_OFF(zclient->t_write);
return ZCLIENT_SEND_SUCCESS;
case BUFFER_PENDING:
- thread_add_write(zclient->master, zclient_flush_data, zclient,
- zclient->sock, &zclient->t_write);
+ event_add_write(zclient->master, zclient_flush_data, zclient,
+ zclient->sock, &zclient->t_write);
return ZCLIENT_SEND_BUFFERED;
}
/* This function is a wrapper function for calling zclient_start from
timer or event thread. */
-static void zclient_connect(struct thread *t)
+static void zclient_connect(struct event *t)
{
struct zclient *zclient;
- zclient = THREAD_ARG(t);
+ zclient = EVENT_ARG(t);
zclient->t_connect = NULL;
if (zclient_debug)
};
/* Zebra client message read function. */
-static void zclient_read(struct thread *thread)
+static void zclient_read(struct event *thread)
{
size_t already;
uint16_t length, command;
struct zclient *zclient;
/* Get socket to zebra. */
- zclient = THREAD_ARG(thread);
+ zclient = EVENT_ARG(thread);
zclient->t_read = NULL;
/* Read zebra header (if we don't have it already). */
{
switch (event) {
case ZCLIENT_SCHEDULE:
- thread_add_event(zclient->master, zclient_connect, zclient, 0,
- &zclient->t_connect);
+ event_add_event(zclient->master, zclient_connect, zclient, 0,
+ &zclient->t_connect);
break;
case ZCLIENT_CONNECT:
if (zclient_debug)
zlog_debug(
"zclient connect failures: %d schedule interval is now %d",
zclient->fail, zclient->fail < 3 ? 10 : 60);
- thread_add_timer(zclient->master, zclient_connect, zclient,
- zclient->fail < 3 ? 10 : 60,
- &zclient->t_connect);
+ event_add_timer(zclient->master, zclient_connect, zclient,
+ zclient->fail < 3 ? 10 : 60,
+ &zclient->t_connect);
break;
case ZCLIENT_READ:
zclient->t_read = NULL;
- thread_add_read(zclient->master, zclient_read, zclient,
- zclient->sock, &zclient->t_read);
+ event_add_read(zclient->master, zclient_read, zclient,
+ zclient->sock, &zclient->t_read);
break;
}
}
/* Structure for the zebra client. */
struct zclient {
/* The thread master we schedule ourselves on */
- struct thread_master *master;
+ struct event_loop *master;
/* Privileges to change socket values */
struct zebra_privs_t *privs;
struct buffer *wb;
/* Read and connect thread. */
- struct thread *t_read;
- struct thread *t_connect;
+ struct event *t_read;
+ struct event *t_connect;
/* Thread to write buffered data to zebra. */
- struct thread *t_write;
+ struct event *t_write;
/* Redistribute information. */
uint8_t redist_default; /* clients protocol */
extern uint32_t zclient_get_nhg_start(uint32_t proto);
-extern struct zclient *zclient_new(struct thread_master *m,
+extern struct zclient *zclient_new(struct event_loop *m,
struct zclient_options *opt,
zclient_handler *const *handlers,
size_t n_handlers);
#include "frrcu.h"
#include "zlog.h"
#include "libfrr_trace.h"
-#include "thread.h"
+#include "frrevent.h"
DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message");
DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer");
static void zlog_backtrace_msg(const struct xref_logmsg *xref, int prio)
{
- struct thread *tc = pthread_getspecific(thread_current);
+ struct event *tc = pthread_getspecific(thread_current);
const char *uid = xref->xref.xrefdata->uid;
bool found_thread = false;
#include "frr_pthread.h"
#include "command.h"
#include "monotime.h"
-#include "thread.h"
+#include "frrevent.h"
#include "lib/version.h"
#include "lib/lib_errors.h"
rcu_free(MTYPE_LOG_5424, oldt, zt.rcu_head);
}
-static void zlog_5424_reconnect(struct thread *t)
+static void zlog_5424_reconnect(struct event *t)
{
- struct zlog_cfg_5424 *zcf = THREAD_ARG(t);
- int fd = THREAD_FD(t);
+ struct zlog_cfg_5424 *zcf = EVENT_ARG(t);
+ int fd = EVENT_FD(t);
char dummy[256];
ssize_t ret;
ret = read(fd, dummy, sizeof(dummy));
if (ret > 0) {
/* logger is sending us something?!?! */
- thread_add_read(t->master, zlog_5424_reconnect, zcf, fd,
- &zcf->t_reconnect);
+ event_add_read(t->master, zlog_5424_reconnect, zcf, fd,
+ &zcf->t_reconnect);
return;
}
assert(zcf->master);
if (fd != -1) {
- thread_add_read(zcf->master, zlog_5424_reconnect, zcf,
- fd, &zcf->t_reconnect);
+ event_add_read(zcf->master, zlog_5424_reconnect, zcf,
+ fd, &zcf->t_reconnect);
zcf->reconn_backoff_cur = zcf->reconn_backoff;
} else {
- thread_add_timer_msec(zcf->master, zlog_5424_reconnect,
- zcf, zcf->reconn_backoff_cur,
- &zcf->t_reconnect);
+ event_add_timer_msec(zcf->master, zlog_5424_reconnect,
+ zcf, zcf->reconn_backoff_cur,
+ &zcf->t_reconnect);
zcf->reconn_backoff_cur += zcf->reconn_backoff_cur / 2;
if (zcf->reconn_backoff_cur > zcf->reconn_backoff_max)
{
int fd = -1;
- thread_cancel(&zcf->t_reconnect);
+ event_cancel(&zcf->t_reconnect);
if (zcf->prio_min != ZLOG_DISABLED)
fd = zlog_5424_open(zcf, -1);
if (!zcf->active)
return true;
- thread_cancel(&zcf->t_reconnect);
+ event_cancel(&zcf->t_reconnect);
/* need to retain the socket type because it also influences
* other fields (packets) and we can't atomically swap these
#include "zlog_targets.h"
#include "qobj.h"
-struct thread;
-struct thread_master;
+struct event;
+struct event_loop;
enum zlog_5424_dst {
/* can be used to disable a target temporarily */
*/
/* sockets only - read handler to reconnect on errors */
- struct thread_master *master;
- struct thread *t_reconnect;
+ struct event_loop *master;
+ struct event *t_reconnect;
unsigned int reconn_backoff, reconn_backoff_cur, reconn_backoff_max;
int sock_type;
struct sockaddr_storage sa;
DEFINE_QOBJ_TYPE(zlog_cfg_5424_user);
static struct targets_head targets = INIT_RBTREE_UNIQ(targets);
-static struct thread_master *log_5424_master;
+static struct event_loop *log_5424_master;
static void clear_dst(struct zlog_cfg_5424_user *cfg);
/* hooks */
-static int log_5424_early_init(struct thread_master *master);
+static int log_5424_early_init(struct event_loop *master);
static int log_5424_rotate(void);
static int log_5424_fini(void);
hook_register(frr_fini, log_5424_fini);
}
-static int log_5424_early_init(struct thread_master *master)
+static int log_5424_early_init(struct event_loop *master)
{
log_5424_master = master;
/* MGMTD process wide configuration pointer to export. */
struct mgmt_master *mm;
-void mgmt_master_init(struct thread_master *master, const int buffer_size)
+void mgmt_master_init(struct event_loop *master, const int buffer_size)
{
memset(&mgmt_master, 0, sizeof(struct mgmt_master));
* MGMTD master for system wide configurations and variables.
*/
struct mgmt_master {
- struct thread_master *master;
+ struct event_loop *master;
/* How big should we set the socket buffer size */
uint32_t socket_buffer;
extern int mgmt_config_write(struct vty *vty);
-extern void mgmt_master_init(struct thread_master *master,
- const int buffer_size);
+extern void mgmt_master_init(struct event_loop *master, const int buffer_size);
extern void mgmt_init(void);
extern void mgmt_vty_init(void);
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "sockopt.h"
#include "network.h"
#include "libfrr.h"
mgmt_xpath_map[MGMTD_BE_MAX_NUM_XPATH_MAP];
static int mgmt_num_xpath_maps;
-static struct thread_master *mgmt_be_adapter_tm;
+static struct event_loop *mgmt_be_adapter_tm;
static struct mgmt_be_adapters_head mgmt_be_adapters;
mgmtd__be_message__free_unpacked(be_msg, NULL);
}
-static void mgmt_be_adapter_proc_msgbufs(struct thread *thread)
+static void mgmt_be_adapter_proc_msgbufs(struct event *thread)
{
- struct mgmt_be_client_adapter *adapter = THREAD_ARG(thread);
+ struct mgmt_be_client_adapter *adapter = EVENT_ARG(thread);
if (mgmt_msg_procbufs(&adapter->mstate, mgmt_be_adapter_process_msg,
adapter, mgmt_debug_be))
mgmt_be_adapter_register_event(adapter, MGMTD_BE_PROC_MSG);
}
-static void mgmt_be_adapter_read(struct thread *thread)
+static void mgmt_be_adapter_read(struct event *thread)
{
struct mgmt_be_client_adapter *adapter;
enum mgmt_msg_rsched rv;
- adapter = (struct mgmt_be_client_adapter *)THREAD_ARG(thread);
+ adapter = (struct mgmt_be_client_adapter *)EVENT_ARG(thread);
rv = mgmt_msg_read(&adapter->mstate, adapter->conn_fd, mgmt_debug_be);
if (rv == MSR_DISCONNECT) {
mgmt_be_adapter_register_event(adapter, MGMTD_BE_CONN_READ);
}
-static void mgmt_be_adapter_write(struct thread *thread)
+static void mgmt_be_adapter_write(struct event *thread)
{
- struct mgmt_be_client_adapter *adapter = THREAD_ARG(thread);
+ struct mgmt_be_client_adapter *adapter = EVENT_ARG(thread);
enum mgmt_msg_wsched rv;
rv = mgmt_msg_write(&adapter->mstate, adapter->conn_fd, mgmt_debug_be);
assert(rv == MSW_SCHED_NONE);
}
-static void mgmt_be_adapter_resume_writes(struct thread *thread)
+static void mgmt_be_adapter_resume_writes(struct event *thread)
{
struct mgmt_be_client_adapter *adapter;
- adapter = (struct mgmt_be_client_adapter *)THREAD_ARG(thread);
+ adapter = (struct mgmt_be_client_adapter *)EVENT_ARG(thread);
assert(adapter && adapter->conn_fd >= 0);
mgmt_be_adapter_writes_on(adapter);
nb_config_diff_created(node, seq, root);
}
-static void mgmt_be_adapter_conn_init(struct thread *thread)
+static void mgmt_be_adapter_conn_init(struct event *thread)
{
struct mgmt_be_client_adapter *adapter;
- adapter = (struct mgmt_be_client_adapter *)THREAD_ARG(thread);
+ adapter = (struct mgmt_be_client_adapter *)EVENT_ARG(thread);
assert(adapter && adapter->conn_fd >= 0);
/*
switch (event) {
case MGMTD_BE_CONN_INIT:
- thread_add_timer_msec(mgmt_be_adapter_tm,
+ event_add_timer_msec(mgmt_be_adapter_tm,
mgmt_be_adapter_conn_init, adapter,
MGMTD_BE_CONN_INIT_DELAY_MSEC,
&adapter->conn_init_ev);
- assert(adapter->conn_init_ev);
break;
case MGMTD_BE_CONN_READ:
- thread_add_read(mgmt_be_adapter_tm, mgmt_be_adapter_read,
+ event_add_read(mgmt_be_adapter_tm, mgmt_be_adapter_read,
adapter, adapter->conn_fd, &adapter->conn_read_ev);
- assert(adapter->conn_read_ev);
break;
case MGMTD_BE_CONN_WRITE:
if (adapter->conn_write_ev)
MGMTD_BE_ADAPTER_DBG(
"scheduling write ready notify for client %s",
adapter->name);
- thread_add_write(mgmt_be_adapter_tm, mgmt_be_adapter_write,
+ event_add_write(mgmt_be_adapter_tm, mgmt_be_adapter_write,
adapter, adapter->conn_fd, &adapter->conn_write_ev);
assert(adapter->conn_write_ev);
break;
case MGMTD_BE_PROC_MSG:
tv.tv_usec = MGMTD_BE_MSG_PROC_DELAY_USEC;
- thread_add_timer_tv(mgmt_be_adapter_tm,
+ event_add_timer_tv(mgmt_be_adapter_tm,
mgmt_be_adapter_proc_msgbufs, adapter, &tv,
&adapter->proc_msg_ev);
- assert(adapter->proc_msg_ev);
break;
case MGMTD_BE_CONN_WRITES_ON:
- thread_add_timer_msec(mgmt_be_adapter_tm,
+ event_add_timer_msec(mgmt_be_adapter_tm,
mgmt_be_adapter_resume_writes, adapter,
MGMTD_BE_MSG_WRITE_DELAY_MSEC,
&adapter->conn_writes_on);
- assert(adapter->conn_writes_on);
break;
case MGMTD_BE_SERVER:
case MGMTD_BE_SCHED_CFG_PREPARE:
(*adapter)->refcount--;
if (!(*adapter)->refcount) {
mgmt_be_adapters_del(&mgmt_be_adapters, *adapter);
- THREAD_OFF((*adapter)->conn_init_ev);
- THREAD_OFF((*adapter)->conn_read_ev);
- THREAD_OFF((*adapter)->conn_write_ev);
- THREAD_OFF((*adapter)->conn_writes_on);
- THREAD_OFF((*adapter)->proc_msg_ev);
+ EVENT_OFF((*adapter)->conn_init_ev);
+ EVENT_OFF((*adapter)->conn_read_ev);
+ EVENT_OFF((*adapter)->conn_write_ev);
+ EVENT_OFF((*adapter)->conn_writes_on);
+ EVENT_OFF((*adapter)->proc_msg_ev);
mgmt_msg_destroy(&(*adapter)->mstate);
XFREE(MTYPE_MGMTD_BE_ADPATER, *adapter);
}
*adapter = NULL;
}
-int mgmt_be_adapter_init(struct thread_master *tm)
+int mgmt_be_adapter_init(struct event_loop *tm)
{
if (!mgmt_be_adapter_tm) {
mgmt_be_adapter_tm = tm;
enum mgmt_be_client_id id;
int conn_fd;
union sockunion conn_su;
- struct thread *conn_init_ev;
- struct thread *conn_read_ev;
- struct thread *conn_write_ev;
- struct thread *conn_writes_on;
- struct thread *proc_msg_ev;
+ struct event *conn_init_ev;
+ struct event *conn_read_ev;
+ struct event *conn_write_ev;
+ struct event *conn_writes_on;
+ struct event *proc_msg_ev;
uint32_t flags;
char name[MGMTD_CLIENT_NAME_MAX_LEN];
uint8_t num_xpath_reg;
};
/* Initialise backend adapter module. */
-extern int mgmt_be_adapter_init(struct thread_master *tm);
+extern int mgmt_be_adapter_init(struct event_loop *tm);
/* Destroy the backend adapter module. */
extern void mgmt_be_adapter_destroy(void);
#endif /* REDIRECT_DEBUG_TO_STDERR */
static int mgmt_be_listen_fd = -1;
-static struct thread_master *mgmt_be_listen_tm;
-static struct thread *mgmt_be_listen_ev;
+static struct event_loop *mgmt_be_listen_tm;
+static struct event *mgmt_be_listen_ev;
static void mgmt_be_server_register_event(enum mgmt_be_event event);
-static void mgmt_be_conn_accept(struct thread *thread)
+static void mgmt_be_conn_accept(struct event *thread)
{
int client_conn_fd;
union sockunion su;
static void mgmt_be_server_register_event(enum mgmt_be_event event)
{
if (event == MGMTD_BE_SERVER) {
- thread_add_read(mgmt_be_listen_tm, mgmt_be_conn_accept,
+ event_add_read(mgmt_be_listen_tm, mgmt_be_conn_accept,
NULL, mgmt_be_listen_fd,
&mgmt_be_listen_ev);
assert(mgmt_be_listen_ev);
exit(-1);
}
-int mgmt_be_server_init(struct thread_master *master)
+int mgmt_be_server_init(struct event_loop *master)
{
if (mgmt_be_listen_tm) {
MGMTD_BE_SRVR_DBG("MGMTD Backend Server already running!");
MGMTD_BE_SRVR_DBG("Closing MGMTD Backend Server!");
if (mgmt_be_listen_ev) {
- THREAD_OFF(mgmt_be_listen_ev);
+ EVENT_OFF(mgmt_be_listen_ev);
mgmt_be_listen_ev = NULL;
}
#define MGMTD_BE_MAX_CONN 32
/* Initialise backend server */
-extern int mgmt_be_server_init(struct thread_master *master);
+extern int mgmt_be_server_init(struct event_loop *master);
/* Destroy backend server */
extern void mgmt_be_server_destroy(void);
uint8_t ds_write_locked[MGMTD_DS_MAX_ID];
uint8_t ds_read_locked[MGMTD_DS_MAX_ID];
uint8_t ds_locked_implict[MGMTD_DS_MAX_ID];
- struct thread *proc_cfg_txn_clnp;
- struct thread *proc_show_txn_clnp;
+ struct event *proc_cfg_txn_clnp;
+ struct event *proc_show_txn_clnp;
struct mgmt_fe_sessions_item list_linkage;
};
#define FOREACH_SESSION_IN_LIST(adapter, session) \
frr_each_safe (mgmt_fe_sessions, &(adapter)->fe_sessions, (session))
-static struct thread_master *mgmt_fe_adapter_tm;
+static struct event_loop *mgmt_fe_adapter_tm;
static struct mgmt_master *mgmt_fe_adapter_mm;
static struct mgmt_fe_adapters_head mgmt_fe_adapters;
return mgmt_fe_adapter_send_msg(session->adapter, &fe_msg);
}
-static void mgmt_fe_session_cfg_txn_clnup(struct thread *thread)
+static void mgmt_fe_session_cfg_txn_clnup(struct event *thread)
{
struct mgmt_fe_session_ctx *session;
- session = (struct mgmt_fe_session_ctx *)THREAD_ARG(thread);
+ session = (struct mgmt_fe_session_ctx *)EVENT_ARG(thread);
mgmt_fe_session_cfg_txn_cleanup(session);
}
-static void mgmt_fe_session_show_txn_clnup(struct thread *thread)
+static void mgmt_fe_session_show_txn_clnup(struct event *thread)
{
struct mgmt_fe_session_ctx *session;
- session = (struct mgmt_fe_session_ctx *)THREAD_ARG(thread);
+ session = (struct mgmt_fe_session_ctx *)EVENT_ARG(thread);
mgmt_fe_session_show_txn_cleanup(session);
}
switch (event) {
case MGMTD_FE_SESSION_CFG_TXN_CLNUP:
- thread_add_timer_tv(mgmt_fe_adapter_tm,
+ event_add_timer_tv(mgmt_fe_adapter_tm,
mgmt_fe_session_cfg_txn_clnup, session,
&tv, &session->proc_cfg_txn_clnp);
- assert(session->proc_cfg_txn_clnp);
break;
case MGMTD_FE_SESSION_SHOW_TXN_CLNUP:
- thread_add_timer_tv(mgmt_fe_adapter_tm,
+ event_add_timer_tv(mgmt_fe_adapter_tm,
mgmt_fe_session_show_txn_clnup, session,
&tv, &session->proc_show_txn_clnp);
- assert(session->proc_show_txn_clnp);
break;
}
}
mgmtd__fe_message__free_unpacked(fe_msg, NULL);
}
-static void mgmt_fe_adapter_proc_msgbufs(struct thread *thread)
+static void mgmt_fe_adapter_proc_msgbufs(struct event *thread)
{
- struct mgmt_fe_client_adapter *adapter = THREAD_ARG(thread);
+ struct mgmt_fe_client_adapter *adapter = EVENT_ARG(thread);
if (mgmt_msg_procbufs(&adapter->mstate, mgmt_fe_adapter_process_msg,
adapter, mgmt_debug_fe))
mgmt_fe_adapter_register_event(adapter, MGMTD_FE_PROC_MSG);
}
-static void mgmt_fe_adapter_read(struct thread *thread)
+static void mgmt_fe_adapter_read(struct event *thread)
{
- struct mgmt_fe_client_adapter *adapter = THREAD_ARG(thread);
+ struct mgmt_fe_client_adapter *adapter = EVENT_ARG(thread);
enum mgmt_msg_rsched rv;
rv = mgmt_msg_read(&adapter->mstate, adapter->conn_fd, mgmt_debug_fe);
mgmt_fe_adapter_register_event(adapter, MGMTD_FE_CONN_READ);
}
-static void mgmt_fe_adapter_write(struct thread *thread)
+static void mgmt_fe_adapter_write(struct event *thread)
{
- struct mgmt_fe_client_adapter *adapter = THREAD_ARG(thread);
+ struct mgmt_fe_client_adapter *adapter = EVENT_ARG(thread);
enum mgmt_msg_wsched rv;
rv = mgmt_msg_write(&adapter->mstate, adapter->conn_fd, mgmt_debug_fe);
assert(rv == MSW_SCHED_NONE);
}
-static void mgmt_fe_adapter_resume_writes(struct thread *thread)
+static void mgmt_fe_adapter_resume_writes(struct event *thread)
{
struct mgmt_fe_client_adapter *adapter;
- adapter = (struct mgmt_fe_client_adapter *)THREAD_ARG(thread);
+ adapter = (struct mgmt_fe_client_adapter *)EVENT_ARG(thread);
assert(adapter && adapter->conn_fd != -1);
mgmt_fe_adapter_writes_on(adapter);
switch (event) {
case MGMTD_FE_CONN_READ:
- thread_add_read(mgmt_fe_adapter_tm, mgmt_fe_adapter_read,
+ event_add_read(mgmt_fe_adapter_tm, mgmt_fe_adapter_read,
adapter, adapter->conn_fd, &adapter->conn_read_ev);
- assert(adapter->conn_read_ev);
break;
case MGMTD_FE_CONN_WRITE:
- thread_add_write(mgmt_fe_adapter_tm,
+ event_add_write(mgmt_fe_adapter_tm,
mgmt_fe_adapter_write, adapter,
adapter->conn_fd, &adapter->conn_write_ev);
- assert(adapter->conn_write_ev);
break;
case MGMTD_FE_PROC_MSG:
tv.tv_usec = MGMTD_FE_MSG_PROC_DELAY_USEC;
- thread_add_timer_tv(mgmt_fe_adapter_tm,
+ event_add_timer_tv(mgmt_fe_adapter_tm,
mgmt_fe_adapter_proc_msgbufs, adapter,
&tv, &adapter->proc_msg_ev);
- assert(adapter->proc_msg_ev);
break;
case MGMTD_FE_CONN_WRITES_ON:
- thread_add_timer_msec(mgmt_fe_adapter_tm,
+ event_add_timer_msec(mgmt_fe_adapter_tm,
mgmt_fe_adapter_resume_writes, adapter,
MGMTD_FE_MSG_WRITE_DELAY_MSEC,
&adapter->conn_writes_on);
- assert(adapter->conn_writes_on);
break;
case MGMTD_FE_SERVER:
assert(!"mgmt_fe_adapter_post_event() called incorrectly");
(*adapter)->refcount--;
if (!(*adapter)->refcount) {
mgmt_fe_adapters_del(&mgmt_fe_adapters, *adapter);
- THREAD_OFF((*adapter)->conn_read_ev);
- THREAD_OFF((*adapter)->conn_write_ev);
- THREAD_OFF((*adapter)->proc_msg_ev);
- THREAD_OFF((*adapter)->conn_writes_on);
+ EVENT_OFF((*adapter)->conn_read_ev);
+ EVENT_OFF((*adapter)->conn_write_ev);
+ EVENT_OFF((*adapter)->proc_msg_ev);
+ EVENT_OFF((*adapter)->conn_writes_on);
mgmt_msg_destroy(&(*adapter)->mstate);
XFREE(MTYPE_MGMTD_FE_ADPATER, *adapter);
}
*adapter = NULL;
}
-int mgmt_fe_adapter_init(struct thread_master *tm, struct mgmt_master *mm)
+int mgmt_fe_adapter_init(struct event_loop *tm, struct mgmt_master *mm)
{
if (!mgmt_fe_adapter_tm) {
mgmt_fe_adapter_tm = tm;
struct mgmt_fe_client_adapter {
int conn_fd;
union sockunion conn_su;
- struct thread *conn_read_ev;
- struct thread *conn_write_ev;
- struct thread *conn_writes_on;
- struct thread *proc_msg_ev;
+ struct event *conn_read_ev;
+ struct event *conn_write_ev;
+ struct event *conn_writes_on;
+ struct event *proc_msg_ev;
uint32_t flags;
char name[MGMTD_CLIENT_NAME_MAX_LEN];
DECLARE_LIST(mgmt_fe_adapters, struct mgmt_fe_client_adapter, list_linkage);
/* Initialise frontend adapter module */
-extern int mgmt_fe_adapter_init(struct thread_master *tm,
- struct mgmt_master *cm);
+extern int mgmt_fe_adapter_init(struct event_loop *tm, struct mgmt_master *cm);
/* Destroy frontend adapter module */
extern void mgmt_fe_adapter_destroy(void);
#endif /* REDIRECT_DEBUG_TO_STDERR */
static int mgmt_fe_listen_fd = -1;
-static struct thread_master *mgmt_fe_listen_tm;
-static struct thread *mgmt_fe_listen_ev;
+static struct event_loop *mgmt_fe_listen_tm;
+static struct event *mgmt_fe_listen_ev;
static void mgmt_fe_server_register_event(enum mgmt_fe_event event);
-static void mgmt_fe_conn_accept(struct thread *thread)
+static void mgmt_fe_conn_accept(struct event *thread)
{
int client_conn_fd;
union sockunion su;
static void mgmt_fe_server_register_event(enum mgmt_fe_event event)
{
if (event == MGMTD_FE_SERVER) {
- thread_add_read(mgmt_fe_listen_tm, mgmt_fe_conn_accept,
+ event_add_read(mgmt_fe_listen_tm, mgmt_fe_conn_accept,
NULL, mgmt_fe_listen_fd,
&mgmt_fe_listen_ev);
assert(mgmt_fe_listen_ev);
exit(-1);
}
-int mgmt_fe_server_init(struct thread_master *master)
+int mgmt_fe_server_init(struct event_loop *master)
{
if (mgmt_fe_listen_tm) {
MGMTD_FE_SRVR_DBG("MGMTD Frontend Server already running!");
MGMTD_FE_SRVR_DBG("Closing MGMTD Frontend Server!");
if (mgmt_fe_listen_ev) {
- THREAD_OFF(mgmt_fe_listen_ev);
+ EVENT_OFF(mgmt_fe_listen_ev);
mgmt_fe_listen_ev = NULL;
}
#define MGMTD_FE_MAX_CONN 32
/* Initialise frontend server */
-extern int mgmt_fe_server_init(struct thread_master *master);
+extern int mgmt_fe_server_init(struct event_loop *master);
/* Destroy frontend server */
extern void mgmt_fe_server_destroy(void);
#include <zebra.h>
#include "md5.h"
-#include "thread.h"
+#include "frrevent.h"
#include "xref.h"
#include "mgmt_fe_client.h"
} else {
zlog_err("More records found in index file %s",
MGMTD_COMMIT_INDEX_FILE_NAME);
+ fclose(fp);
return false;
}
/* struct mgmt_master *mm; */
- struct thread *proc_set_cfg;
- struct thread *proc_comm_cfg;
- struct thread *proc_get_cfg;
- struct thread *proc_get_data;
- struct thread *comm_cfg_timeout;
- struct thread *clnup;
+ struct event *proc_set_cfg;
+ struct event *proc_comm_cfg;
+ struct event *proc_get_cfg;
+ struct event *proc_get_data;
+ struct event *comm_cfg_timeout;
+ struct event *clnup;
/* List of backend adapters involved in this transaction */
struct mgmt_txn_badapters_head be_adapters;
mgmt_txn_send_be_txn_delete(struct mgmt_txn_ctx *txn,
struct mgmt_be_client_adapter *adapter);
-static struct thread_master *mgmt_txn_tm;
+static struct event_loop *mgmt_txn_tm;
static struct mgmt_master *mgmt_txn_mm;
static void mgmt_txn_register_event(struct mgmt_txn_ctx *txn,
*txn_req = NULL;
}
-static void mgmt_txn_process_set_cfg(struct thread *thread)
+static void mgmt_txn_process_set_cfg(struct event *thread)
{
struct mgmt_txn_ctx *txn;
struct mgmt_txn_req *txn_req;
struct mgmt_commit_stats *cmt_stats;
int ret = 0;
- txn = (struct mgmt_txn_ctx *)THREAD_ARG(thread);
+ txn = (struct mgmt_txn_ctx *)EVENT_ARG(thread);
assert(txn);
cmt_stats = mgmt_fe_get_session_commit_stats(txn->session_id);
if (success) {
/* Stop the commit-timeout timer */
- THREAD_OFF(txn->comm_cfg_timeout);
+ EVENT_OFF(txn->comm_cfg_timeout);
create_cmt_info_rec =
(result != MGMTD_NO_CFG_CHANGES &&
return 0;
}
-static void mgmt_txn_cfg_commit_timedout(struct thread *thread)
+static void mgmt_txn_cfg_commit_timedout(struct event *thread)
{
struct mgmt_txn_ctx *txn;
- txn = (struct mgmt_txn_ctx *)THREAD_ARG(thread);
+ txn = (struct mgmt_txn_ctx *)EVENT_ARG(thread);
assert(txn);
assert(txn->type == MGMTD_TXN_TYPE_CONFIG);
return 0;
}
-static void mgmt_txn_process_commit_cfg(struct thread *thread)
+static void mgmt_txn_process_commit_cfg(struct event *thread)
{
struct mgmt_txn_ctx *txn;
struct mgmt_commit_cfg_req *cmtcfg_req;
- txn = (struct mgmt_txn_ctx *)THREAD_ARG(thread);
+ txn = (struct mgmt_txn_ctx *)EVENT_ARG(thread);
assert(txn);
MGMTD_TXN_DBG(
* cleanup. Please see mgmt_fe_send_commit_cfg_reply() for
* more details.
*/
- THREAD_OFF(txn->comm_cfg_timeout);
+ EVENT_OFF(txn->comm_cfg_timeout);
mgmt_txn_send_commit_cfg_reply(txn, MGMTD_SUCCESS, NULL);
break;
case MGMTD_COMMIT_PHASE_MAX:
return 0;
}
-static void mgmt_txn_process_get_cfg(struct thread *thread)
+static void mgmt_txn_process_get_cfg(struct event *thread)
{
struct mgmt_txn_ctx *txn;
struct mgmt_txn_req *txn_req;
int num_processed = 0;
bool error;
- txn = (struct mgmt_txn_ctx *)THREAD_ARG(thread);
+ txn = (struct mgmt_txn_ctx *)EVENT_ARG(thread);
assert(txn);
MGMTD_TXN_DBG(
}
}
-static void mgmt_txn_process_get_data(struct thread *thread)
+static void mgmt_txn_process_get_data(struct event *thread)
{
struct mgmt_txn_ctx *txn;
struct mgmt_txn_req *txn_req;
int num_processed = 0;
bool error;
- txn = (struct mgmt_txn_ctx *)THREAD_ARG(thread);
+ txn = (struct mgmt_txn_ctx *)EVENT_ARG(thread);
assert(txn);
MGMTD_TXN_DBG(
if ((*txn)->type == MGMTD_TXN_TYPE_CONFIG)
if (mgmt_txn_mm->cfg_txn == *txn)
mgmt_txn_mm->cfg_txn = NULL;
- THREAD_OFF((*txn)->proc_get_cfg);
- THREAD_OFF((*txn)->proc_get_data);
- THREAD_OFF((*txn)->proc_comm_cfg);
- THREAD_OFF((*txn)->comm_cfg_timeout);
+ EVENT_OFF((*txn)->proc_get_cfg);
+ EVENT_OFF((*txn)->proc_get_data);
+ EVENT_OFF((*txn)->proc_comm_cfg);
+ EVENT_OFF((*txn)->comm_cfg_timeout);
hash_release(mgmt_txn_mm->txn_hash, *txn);
mgmt_txns_del(&mgmt_txn_mm->txn_list, *txn);
mgmt_txn_cleanup_txn(&txn);
}
-static void mgmt_txn_cleanup(struct thread *thread)
+static void mgmt_txn_cleanup(struct event *thread)
{
struct mgmt_txn_ctx *txn;
- txn = (struct mgmt_txn_ctx *)THREAD_ARG(thread);
+ txn = (struct mgmt_txn_ctx *)EVENT_ARG(thread);
assert(txn);
mgmt_txn_cleanup_txn(&txn);
switch (event) {
case MGMTD_TXN_PROC_SETCFG:
- thread_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_set_cfg,
+ event_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_set_cfg,
txn, &tv, &txn->proc_set_cfg);
- assert(txn->proc_set_cfg);
break;
case MGMTD_TXN_PROC_COMMITCFG:
- thread_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_commit_cfg,
+ event_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_commit_cfg,
txn, &tv, &txn->proc_comm_cfg);
- assert(txn->proc_comm_cfg);
break;
case MGMTD_TXN_PROC_GETCFG:
- thread_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_get_cfg,
+ event_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_get_cfg,
txn, &tv, &txn->proc_get_cfg);
- assert(txn->proc_get_cfg);
break;
case MGMTD_TXN_PROC_GETDATA:
- thread_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_get_data,
+ event_add_timer_tv(mgmt_txn_tm, mgmt_txn_process_get_data,
txn, &tv, &txn->proc_get_data);
- assert(txn->proc_get_data);
break;
case MGMTD_TXN_COMMITCFG_TIMEOUT:
- thread_add_timer_msec(mgmt_txn_tm,
+ event_add_timer_msec(mgmt_txn_tm,
mgmt_txn_cfg_commit_timedout, txn,
MGMTD_TXN_CFG_COMMIT_MAX_DELAY_MSEC,
&txn->comm_cfg_timeout);
- assert(txn->comm_cfg_timeout);
break;
case MGMTD_TXN_CLEANUP:
tv.tv_usec = MGMTD_TXN_CLEANUP_DELAY_USEC;
- thread_add_timer_tv(mgmt_txn_tm, mgmt_txn_cleanup, txn, &tv,
+ event_add_timer_tv(mgmt_txn_tm, mgmt_txn_cleanup, txn, &tv,
&txn->clnup);
- assert(txn->clnup);
}
}
-int mgmt_txn_init(struct mgmt_master *mm, struct thread_master *tm)
+int mgmt_txn_init(struct mgmt_master *mm, struct event_loop *tm)
{
if (mgmt_txn_mm || mgmt_txn_tm)
assert(!"MGMTD TXN: Call txn_init() only once");
}
/* Initialise transaction module. */
-extern int mgmt_txn_init(struct mgmt_master *cm, struct thread_master *tm);
+extern int mgmt_txn_init(struct mgmt_master *cm, struct event_loop *tm);
/* Destroy the transaction module. */
extern void mgmt_txn_destroy(void);
.config_write = config_write_mgmt_debug,
};
-static int config_write_mgmt_debug(struct vty *vty)
+static int config_write_mgmt_debug_helper(struct vty *vty, bool config)
{
int n = mgmt_debug_be + mgmt_debug_fe + mgmt_debug_ds + mgmt_debug_txn;
if (!n)
return 0;
- if (n == 4) {
+
+ if (config && mgmt_debug_be && mgmt_debug_fe && mgmt_debug_ds &&
+ mgmt_debug_txn) {
vty_out(vty, "debug mgmt all\n");
return 0;
}
return 0;
}
-DEFPY(debug_mgmt,
- debug_mgmt_cmd,
+static int config_write_mgmt_debug(struct vty *vty)
+{
+ return config_write_mgmt_debug_helper(vty, true);
+}
+
+DEFUN_NOSH(show_debugging_mgmt, show_debugging_mgmt_cmd,
+ "show debugging [mgmt]", SHOW_STR DEBUG_STR "MGMT Information\n")
+{
+ vty_out(vty, "MGMT debugging status:\n");
+
+ config_write_mgmt_debug_helper(vty, false);
+
+ cmd_show_lib_debugs(vty);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(debug_mgmt, debug_mgmt_cmd,
"[no$no] debug mgmt <all$all|{backend$be|datastore$ds|frontend$fe|transaction$txn}>",
- NO_STR
- DEBUG_STR
- MGMTD_STR
+ NO_STR DEBUG_STR MGMTD_STR
"All debug\n"
"Back-end debug\n"
"Datastore debug\n"
install_element(ENABLE_NODE, &mgmt_performance_measurement_cmd);
install_element(ENABLE_NODE, &mgmt_reset_performance_stats_cmd);
+ install_element(ENABLE_NODE, &show_debugging_mgmt_cmd);
+
/*
* TODO: Register and handlers for auto-completion here.
*/
+++ /dev/null
-/*
- * MGMTD VTY Interface
- * Copyright (C) 2021 Vmware, Inc.
- * Pushpasis Sarkar <spushpasis@vmware.com>
- *
- * This program 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 of the License, or (at your option)
- * any later version.
- *
- * This program 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 "command.h"
-#include "json.h"
-#include "mgmtd/mgmt.h"
-#include "mgmtd/mgmt_be_server.h"
-#include "mgmtd/mgmt_be_adapter.h"
-#include "mgmtd/mgmt_fe_server.h"
-#include "mgmtd/mgmt_fe_adapter.h"
-#include "mgmtd/mgmt_ds.h"
-#include "mgmtd/mgmt_history.h"
-
-#include "mgmtd/mgmt_vty_clippy.c"
-
-DEFPY(show_mgmt_be_adapter,
- show_mgmt_be_adapter_cmd,
- "show mgmt backend-adapter all",
- SHOW_STR
- MGMTD_STR
- MGMTD_BE_ADAPTER_STR
- "Display all Backend Adapters\n")
-{
- mgmt_be_adapter_status_write(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_be_xpath_reg,
- show_mgmt_be_xpath_reg_cmd,
- "show mgmt backend-yang-xpath-registry",
- SHOW_STR
- MGMTD_STR
- "Backend Adapter YANG Xpath Registry\n")
-{
- mgmt_be_xpath_register_write(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_fe_adapter,
- show_mgmt_fe_adapter_cmd,
- "show mgmt frontend-adapter all",
- SHOW_STR MGMTD_STR MGMTD_FE_ADAPTER_STR "Display all Frontend Adapters\n")
-{
- mgmt_fe_adapter_status_write(vty, false);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_fe_adapter_detail, show_mgmt_fe_adapter_detail_cmd,
- "show mgmt frontend-adapter all detail",
- SHOW_STR MGMTD_STR MGMTD_FE_ADAPTER_STR
- "Display all Frontend Adapters\n"
- "Details of commit stats\n")
-{
- mgmt_fe_adapter_status_write(vty, true);
-
- return CMD_SUCCESS;
-}
-
-DEFPY_HIDDEN(mgmt_performance_measurement,
- mgmt_performance_measurement_cmd,
- "[no] mgmt performance-measurement",
- NO_STR
- MGMTD_STR
- "Enable performance measurement\n")
-{
- if (no)
- mgmt_fe_adapter_perf_measurement(vty, false);
- else
- mgmt_fe_adapter_perf_measurement(vty, true);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_reset_performance_stats,
- mgmt_reset_performance_stats_cmd,
- "mgmt reset-statistics",
- MGMTD_STR
- "Reset the Performance measurement statistics\n")
-{
- mgmt_fe_adapter_reset_perf_stats(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_txn,
- show_mgmt_txn_cmd,
- "show mgmt transaction all",
- SHOW_STR
- MGMTD_STR
- MGMTD_TXN_STR
- "Display all Transactions\n")
-{
- mgmt_txn_status_write(vty);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_ds,
- show_mgmt_ds_cmd,
- "show mgmt datastore [all|candidate|operational|running]$dsname",
- SHOW_STR
- MGMTD_STR
- MGMTD_DS_STR
- "All datastores (default)\n"
- "Candidate datastore\n"
- "Operational datastore\n"
- "Running datastore\n")
-{
- struct mgmt_ds_ctx *ds_ctx;
-
- if (!dsname || dsname[0] == 'a') {
- mgmt_ds_status_write(vty);
- return CMD_SUCCESS;
- }
- ds_ctx = mgmt_ds_get_ctx_by_id(mm, mgmt_ds_name2id(dsname));
- if (!ds_ctx) {
- vty_out(vty, "ERROR: Could not access %s datastore!\n", dsname);
- return CMD_ERR_NO_MATCH;
- }
- mgmt_ds_status_write_one(vty, ds_ctx);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_commit,
- mgmt_commit_cmd,
- "mgmt commit <check|apply|abort>$type",
- MGMTD_STR
- "Commit action\n"
- "Validate the set of config commands\n"
- "Validate and apply the set of config commands\n"
- "Abort and drop the set of config commands recently added\n")
-{
- bool validate_only = type[0] == 'c';
- bool abort = type[1] == 'b';
-
- if (vty_mgmt_send_commit_config(vty, validate_only, abort) != 0)
- return CMD_WARNING_CONFIG_FAILED;
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_set_config_data, mgmt_set_config_data_cmd,
- "mgmt set-config WORD$path VALUE",
- MGMTD_STR
- "Set configuration data\n"
- "XPath expression specifying the YANG data path\n"
- "Value of the data to set\n")
-{
- strlcpy(vty->cfg_changes[0].xpath, path,
- sizeof(vty->cfg_changes[0].xpath));
- vty->cfg_changes[0].value = value;
- vty->cfg_changes[0].operation = NB_OP_CREATE;
- vty->num_cfg_changes = 1;
-
- vty->no_implicit_commit = true;
- vty_mgmt_send_config_data(vty);
- vty->no_implicit_commit = false;
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_delete_config_data, mgmt_delete_config_data_cmd,
- "mgmt delete-config WORD$path",
- MGMTD_STR
- "Delete configuration data\n"
- "XPath expression specifying the YANG data path\n")
-{
-
- strlcpy(vty->cfg_changes[0].xpath, path,
- sizeof(vty->cfg_changes[0].xpath));
- vty->cfg_changes[0].value = NULL;
- vty->cfg_changes[0].operation = NB_OP_DESTROY;
- vty->num_cfg_changes = 1;
-
- vty->no_implicit_commit = true;
- vty_mgmt_send_config_data(vty);
- vty->no_implicit_commit = false;
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd,
- "show mgmt get-config [candidate|operational|running]$dsname WORD$path",
- SHOW_STR MGMTD_STR
- "Get configuration data from a specific configuration datastore\n"
- "Candidate datastore (default)\n"
- "Operational datastore\n"
- "Running datastore\n"
- "XPath expression specifying the YANG data path\n")
-{
- const char *xpath_list[VTY_MAXCFGCHANGES] = {0};
- Mgmtd__DatastoreId datastore = MGMTD_DS_CANDIDATE;
-
- if (dsname)
- datastore = mgmt_ds_name2id(dsname);
-
- xpath_list[0] = path;
- vty_mgmt_send_get_config(vty, datastore, xpath_list, 1);
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
- "show mgmt get-data [candidate|operational|running]$dsname WORD$path",
- SHOW_STR MGMTD_STR
- "Get data from a specific datastore\n"
- "Candidate datastore\n"
- "Operational datastore (default)\n"
- "Running datastore\n"
- "XPath expression specifying the YANG data path\n")
-{
- const char *xpath_list[VTY_MAXCFGCHANGES] = {0};
- Mgmtd__DatastoreId datastore = MGMTD_DS_OPERATIONAL;
-
- if (dsname)
- datastore = mgmt_ds_name2id(dsname);
-
- xpath_list[0] = path;
- vty_mgmt_send_get_data(vty, datastore, xpath_list, 1);
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_dump_data,
- show_mgmt_dump_data_cmd,
- "show mgmt datastore-contents [candidate|operational|running]$dsname [xpath WORD$path] [file WORD$filepath] <json|xml>$fmt",
- SHOW_STR
- MGMTD_STR
- "Get Datastore contents from a specific datastore\n"
- "Candidate datastore (default)\n"
- "Operational datastore\n"
- "Running datastore\n"
- "XPath expression specifying the YANG data path\n"
- "XPath string\n"
- "Dump the contents to a file\n"
- "Full path of the file\n"
- "json output\n"
- "xml output\n")
-{
- struct mgmt_ds_ctx *ds_ctx;
- Mgmtd__DatastoreId datastore = MGMTD_DS_CANDIDATE;
- LYD_FORMAT format = fmt[0] == 'j' ? LYD_JSON : LYD_XML;
- FILE *f = NULL;
-
- if (datastore)
- datastore = mgmt_ds_name2id(dsname);
-
- ds_ctx = mgmt_ds_get_ctx_by_id(mm, datastore);
- if (!ds_ctx) {
- vty_out(vty, "ERROR: Could not access datastore!\n");
- return CMD_ERR_NO_MATCH;
- }
-
- if (filepath) {
- f = fopen(filepath, "w");
- if (!f) {
- vty_out(vty,
- "Could not open file pointed by filepath %s\n",
- filepath);
- return CMD_SUCCESS;
- }
- }
-
- mgmt_ds_dump_tree(vty, ds_ctx, path, f, format);
-
- if (f)
- fclose(f);
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_map_xpath,
- show_mgmt_map_xpath_cmd,
- "show mgmt yang-xpath-subscription WORD$path",
- SHOW_STR
- MGMTD_STR
- "Get YANG Backend Subscription\n"
- "XPath expression specifying the YANG data path\n")
-{
- mgmt_be_xpath_subscr_info_write(vty, path);
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_load_config,
- mgmt_load_config_cmd,
- "mgmt load-config WORD$filepath <merge|replace>$type",
- MGMTD_STR
- "Load configuration onto Candidate Datastore\n"
- "Full path of the file\n"
- "Merge configuration with contents of Candidate Datastore\n"
- "Replace the existing contents of Candidate datastore\n")
-{
- bool merge = type[0] == 'm' ? true : false;
- struct mgmt_ds_ctx *ds_ctx;
- int ret;
-
- if (access(filepath, F_OK) == -1) {
- vty_out(vty, "ERROR: File %s : %s\n", filepath,
- strerror(errno));
- return CMD_ERR_NO_FILE;
- }
-
- ds_ctx = mgmt_ds_get_ctx_by_id(mm, MGMTD_DS_CANDIDATE);
- if (!ds_ctx) {
- vty_out(vty, "ERROR: Could not access Candidate datastore!\n");
- return CMD_ERR_NO_MATCH;
- }
-
- ret = mgmt_ds_load_config_from_file(ds_ctx, filepath, merge);
- if (ret != 0)
- vty_out(vty, "Error with parsing the file with error code %d\n",
- ret);
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_save_config,
- mgmt_save_config_cmd,
- "mgmt save-config <candidate|running>$dsname WORD$filepath",
- MGMTD_STR
- "Save configuration from datastore\n"
- "Candidate datastore\n"
- "Running datastore\n"
- "Full path of the file\n")
-{
- Mgmtd__DatastoreId datastore = mgmt_ds_name2id(dsname);
- struct mgmt_ds_ctx *ds_ctx;
- FILE *f;
-
- ds_ctx = mgmt_ds_get_ctx_by_id(mm, datastore);
- if (!ds_ctx) {
- vty_out(vty, "ERROR: Could not access the '%s' datastore!\n",
- dsname);
- return CMD_ERR_NO_MATCH;
- }
-
- if (!filepath) {
- vty_out(vty, "ERROR: No file path mentioned!\n");
- return CMD_ERR_NO_MATCH;
- }
-
- f = fopen(filepath, "w");
- if (!f) {
- vty_out(vty, "Could not open file pointed by filepath %s\n",
- filepath);
- return CMD_SUCCESS;
- }
-
- mgmt_ds_dump_tree(vty, ds_ctx, "/", f, LYD_JSON);
-
- fclose(f);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(show_mgmt_cmt_hist,
- show_mgmt_cmt_hist_cmd,
- "show mgmt commit-history",
- SHOW_STR
- MGMTD_STR
- "Show commit history\n")
-{
- show_mgmt_cmt_history(vty);
- return CMD_SUCCESS;
-}
-
-DEFPY(mgmt_rollback,
- mgmt_rollback_cmd,
- "mgmt rollback <commit-id WORD$commit | last [(1-10)]$last>",
- MGMTD_STR
- "Rollback commits\n"
- "Rollback to commit ID\n"
- "Commit-ID\n"
- "Rollbak n commits\n"
- "Number of commits\n")
-{
- if (commit)
- mgmt_history_rollback_by_id(vty, commit);
- else
- mgmt_history_rollback_n(vty, last);
-
- return CMD_SUCCESS;
-}
-
-static int config_write_mgmt_debug(struct vty *vty);
-static struct cmd_node debug_node = {
- .name = "debug",
- .node = DEBUG_NODE,
- .prompt = "",
- .config_write = config_write_mgmt_debug,
-};
-
-static int config_write_mgmt_debug(struct vty *vty)
-{
- int n = mgmt_debug_be + mgmt_debug_fe + mgmt_debug_ds + mgmt_debug_txn;
- if (!n)
- return 0;
- if (n == 4) {
- vty_out(vty, "debug mgmt all\n");
- return 0;
- }
-
- vty_out(vty, "debug mgmt");
- if (mgmt_debug_be)
- vty_out(vty, " backend");
- if (mgmt_debug_ds)
- vty_out(vty, " datastore");
- if (mgmt_debug_fe)
- vty_out(vty, " frontend");
- if (mgmt_debug_txn)
- vty_out(vty, " transaction");
-
- vty_out(vty, "\n");
-
- return 0;
-}
-
-DEFPY(debug_mgmt,
- debug_mgmt_cmd,
- "[no$no] debug mgmt <all$all|{backend$be|datastore$ds|frontend$fe|transaction$txn}>",
- NO_STR
- DEBUG_STR
- MGMTD_STR
- "All debug\n"
- "Back-end debug\n"
- "Datastore debug\n"
- "Front-end debug\n"
- "Transaction debug\n")
-{
- bool set = !no;
- if (all)
- be = fe = ds = txn = set ? all : NULL;
-
- if (be)
- mgmt_debug_be = set;
- if (ds)
- mgmt_debug_ds = set;
- if (fe)
- mgmt_debug_fe = set;
- if (txn)
- mgmt_debug_txn = set;
-
- return CMD_SUCCESS;
-}
-
-void mgmt_vty_init(void)
-{
- /*
- * Initialize command handling from VTYSH connection.
- * Call command initialization routines defined by
- * backend components that are moved to new MGMTD infra
- * here one by one.
- */
-#if HAVE_STATICD
- extern void static_vty_init(void);
- static_vty_init();
-#endif
-
- install_node(&debug_node);
-
- install_element(VIEW_NODE, &show_mgmt_be_adapter_cmd);
- install_element(VIEW_NODE, &show_mgmt_be_xpath_reg_cmd);
- install_element(VIEW_NODE, &show_mgmt_fe_adapter_cmd);
- install_element(VIEW_NODE, &show_mgmt_fe_adapter_detail_cmd);
- install_element(VIEW_NODE, &show_mgmt_txn_cmd);
- install_element(VIEW_NODE, &show_mgmt_ds_cmd);
- install_element(VIEW_NODE, &show_mgmt_get_config_cmd);
- install_element(VIEW_NODE, &show_mgmt_get_data_cmd);
- install_element(VIEW_NODE, &show_mgmt_dump_data_cmd);
- install_element(VIEW_NODE, &show_mgmt_map_xpath_cmd);
- install_element(VIEW_NODE, &show_mgmt_cmt_hist_cmd);
-
- install_element(CONFIG_NODE, &mgmt_commit_cmd);
- install_element(CONFIG_NODE, &mgmt_set_config_data_cmd);
- install_element(CONFIG_NODE, &mgmt_delete_config_data_cmd);
- install_element(CONFIG_NODE, &mgmt_load_config_cmd);
- install_element(CONFIG_NODE, &mgmt_save_config_cmd);
- install_element(CONFIG_NODE, &mgmt_rollback_cmd);
-
- install_element(VIEW_NODE, &debug_mgmt_cmd);
- install_element(CONFIG_NODE, &debug_mgmt_cmd);
-
- /* Enable view */
- install_element(ENABLE_NODE, &mgmt_performance_measurement_cmd);
- install_element(ENABLE_NODE, &mgmt_reset_performance_stats_cmd);
-
- /*
- * TODO: Register and handlers for auto-completion here.
- */
-}
#include <linux/neighbour.h>
#include <linux/netfilter/nfnetlink_log.h>
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#include "prefix.h"
#include "nhrpd.h"
int netlink_nflog_group;
static int netlink_log_fd = -1;
-static struct thread *netlink_log_thread;
+static struct event *netlink_log_thread;
void netlink_update_binding(struct interface *ifp, union sockunion *proto,
union sockunion *nbma)
nhrp_peer_send_indication(ifp, htons(pkthdr->hw_protocol), &pktpl);
}
-static void netlink_log_recv(struct thread *t)
+static void netlink_log_recv(struct event *t)
{
uint8_t buf[ZNL_BUFFER_SIZE];
- int fd = THREAD_FD(t);
+ int fd = EVENT_FD(t);
struct zbuf payload, zb;
struct nlmsghdr *n;
}
}
- thread_add_read(master, netlink_log_recv, 0, netlink_log_fd,
- &netlink_log_thread);
+ event_add_read(master, netlink_log_recv, 0, netlink_log_fd,
+ &netlink_log_thread);
}
void netlink_set_nflog_group(int nlgroup)
{
if (netlink_log_fd >= 0) {
- thread_cancel(&netlink_log_thread);
+ event_cancel(&netlink_log_thread);
close(netlink_log_fd);
netlink_log_fd = -1;
}
return;
netlink_log_register(netlink_log_fd, nlgroup);
- thread_add_read(master, netlink_log_recv, 0, netlink_log_fd,
- &netlink_log_thread);
+ event_add_read(master, netlink_log_recv, 0, netlink_log_fd,
+ &netlink_log_thread);
}
}
#include "zebra.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "nhrpd.h"
hash_release(nifp->cache_hash, c);
nhrp_peer_unref(c->cur.peer);
nhrp_peer_unref(c->new.peer);
- THREAD_OFF(c->t_timeout);
- THREAD_OFF(c->t_auth);
+ EVENT_OFF(c->t_timeout);
+ EVENT_OFF(c->t_auth);
XFREE(MTYPE_NHRP_CACHE, c);
}
create ? nhrp_cache_alloc : NULL);
}
-static void nhrp_cache_do_free(struct thread *t)
+static void nhrp_cache_do_free(struct event *t)
{
- struct nhrp_cache *c = THREAD_ARG(t);
+ struct nhrp_cache *c = EVENT_ARG(t);
c->t_timeout = NULL;
nhrp_cache_free(c);
}
-static void nhrp_cache_do_timeout(struct thread *t)
+static void nhrp_cache_do_timeout(struct event *t)
{
- struct nhrp_cache *c = THREAD_ARG(t);
+ struct nhrp_cache *c = EVENT_ARG(t);
c->t_timeout = NULL;
if (c->cur.type != NHRP_CACHE_INVALID)
static void nhrp_cache_reset_new(struct nhrp_cache *c)
{
- THREAD_OFF(c->t_auth);
+ EVENT_OFF(c->t_auth);
if (notifier_list_anywhere(&c->newpeer_notifier))
nhrp_peer_notify_del(c->new.peer, &c->newpeer_notifier);
nhrp_peer_unref(c->new.peer);
static void nhrp_cache_update_timers(struct nhrp_cache *c)
{
- THREAD_OFF(c->t_timeout);
+ EVENT_OFF(c->t_timeout);
switch (c->cur.type) {
case NHRP_CACHE_INVALID:
if (!c->t_auth)
- thread_add_timer_msec(master, nhrp_cache_do_free, c, 10,
- &c->t_timeout);
+ event_add_timer_msec(master, nhrp_cache_do_free, c, 10,
+ &c->t_timeout);
break;
case NHRP_CACHE_INCOMPLETE:
case NHRP_CACHE_NEGATIVE:
case NHRP_CACHE_LOCAL:
case NHRP_CACHE_NUM_TYPES:
if (c->cur.expires)
- thread_add_timer(master, nhrp_cache_do_timeout, c,
- c->cur.expires - monotime(NULL),
- &c->t_timeout);
+ event_add_timer(master, nhrp_cache_do_timeout, c,
+ c->cur.expires - monotime(NULL),
+ &c->t_timeout);
break;
}
}
nhrp_cache_update_timers(c);
}
-static void nhrp_cache_do_auth_timeout(struct thread *t)
+static void nhrp_cache_do_auth_timeout(struct event *t)
{
- struct nhrp_cache *c = THREAD_ARG(t);
+ struct nhrp_cache *c = EVENT_ARG(t);
c->t_auth = NULL;
nhrp_cache_authorize_binding(&c->eventid, (void *)"timeout");
}
if (nhrp_peer_check(c->new.peer, 1)) {
evmgr_notify("authorize-binding", c,
nhrp_cache_authorize_binding);
- thread_add_timer(master, nhrp_cache_do_auth_timeout, c,
- 10, &c->t_auth);
+ event_add_timer(master, nhrp_cache_do_auth_timeout, c,
+ 10, &c->t_auth);
}
break;
case NOTIFY_PEER_DOWN:
nhrp_cache_newpeer_notifier);
nhrp_cache_newpeer_notifier(&c->newpeer_notifier,
NOTIFY_PEER_UP);
- thread_add_timer(master, nhrp_cache_do_auth_timeout, c,
- 60, &c->t_auth);
+ event_add_timer(master, nhrp_cache_do_auth_timeout, c,
+ 60, &c->t_auth);
}
}
nhrp_cache_update_timers(c);
#include <sys/socket.h>
#include <sys/un.h>
-#include "thread.h"
+#include "frrevent.h"
#include "zbuf.h"
#include "log.h"
#include "nhrpd.h"
struct nhrp_reqid_pool nhrp_event_reqid;
struct event_manager {
- struct thread *t_reconnect, *t_read, *t_write;
+ struct event *t_reconnect, *t_read, *t_write;
struct zbuf ibuf;
struct zbuf_queue obuf;
int fd;
uint8_t ibuf_data[4 * 1024];
};
-static void evmgr_reconnect(struct thread *t);
+static void evmgr_reconnect(struct event *t);
static void evmgr_connection_error(struct event_manager *evmgr)
{
- THREAD_OFF(evmgr->t_read);
- THREAD_OFF(evmgr->t_write);
+ EVENT_OFF(evmgr->t_read);
+ EVENT_OFF(evmgr->t_write);
zbuf_reset(&evmgr->ibuf);
zbufq_reset(&evmgr->obuf);
close(evmgr->fd);
evmgr->fd = -1;
if (nhrp_event_socket_path)
- thread_add_timer_msec(master, evmgr_reconnect, evmgr, 10,
- &evmgr->t_reconnect);
+ event_add_timer_msec(master, evmgr_reconnect, evmgr, 10,
+ &evmgr->t_reconnect);
}
static void evmgr_recv_message(struct event_manager *evmgr, struct zbuf *zb)
}
}
-static void evmgr_read(struct thread *t)
+static void evmgr_read(struct event *t)
{
- struct event_manager *evmgr = THREAD_ARG(t);
+ struct event_manager *evmgr = EVENT_ARG(t);
struct zbuf *ibuf = &evmgr->ibuf;
struct zbuf msg;
while (zbuf_may_pull_until(ibuf, "\n\n", &msg))
evmgr_recv_message(evmgr, &msg);
- thread_add_read(master, evmgr_read, evmgr, evmgr->fd, &evmgr->t_read);
+ event_add_read(master, evmgr_read, evmgr, evmgr->fd, &evmgr->t_read);
}
-static void evmgr_write(struct thread *t)
+static void evmgr_write(struct event *t)
{
- struct event_manager *evmgr = THREAD_ARG(t);
+ struct event_manager *evmgr = EVENT_ARG(t);
int r;
r = zbufq_write(&evmgr->obuf, evmgr->fd);
if (r > 0) {
- thread_add_write(master, evmgr_write, evmgr, evmgr->fd,
- &evmgr->t_write);
+ event_add_write(master, evmgr_write, evmgr, evmgr->fd,
+ &evmgr->t_write);
} else if (r < 0) {
evmgr_connection_error(evmgr);
}
zbuf_put(obuf, "\n", 1);
zbufq_queue(&evmgr->obuf, obuf);
if (evmgr->fd >= 0)
- thread_add_write(master, evmgr_write, evmgr, evmgr->fd,
- &evmgr->t_write);
+ event_add_write(master, evmgr_write, evmgr, evmgr->fd,
+ &evmgr->t_write);
}
-static void evmgr_reconnect(struct thread *t)
+static void evmgr_reconnect(struct event *t)
{
- struct event_manager *evmgr = THREAD_ARG(t);
+ struct event_manager *evmgr = EVENT_ARG(t);
int fd;
if (evmgr->fd >= 0 || !nhrp_event_socket_path)
zlog_warn("%s: failure connecting nhrp-event socket: %s",
__func__, strerror(errno));
zbufq_reset(&evmgr->obuf);
- thread_add_timer(master, evmgr_reconnect, evmgr, 10,
- &evmgr->t_reconnect);
+ event_add_timer(master, evmgr_reconnect, evmgr, 10,
+ &evmgr->t_reconnect);
return;
}
zlog_info("Connected to Event Manager");
evmgr->fd = fd;
- thread_add_read(master, evmgr_read, evmgr, evmgr->fd, &evmgr->t_read);
+ event_add_read(master, evmgr_read, evmgr, evmgr->fd, &evmgr->t_read);
}
static struct event_manager evmgr_connection;
evmgr->fd = -1;
zbuf_init(&evmgr->ibuf, evmgr->ibuf_data, sizeof(evmgr->ibuf_data), 0);
zbufq_init(&evmgr->obuf);
- thread_add_timer_msec(master, evmgr_reconnect, evmgr, 10,
- &evmgr->t_reconnect);
+ event_add_timer_msec(master, evmgr_reconnect, evmgr, 10,
+ &evmgr->t_reconnect);
}
void evmgr_set_socket(const char *socket)
#include "zebra.h"
#include "linklist.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "nhrpd.h"
#include "os.h"
#include "zebra.h"
#include "privs.h"
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "sigevent.h"
#include "lib/version.h"
#include "log.h"
unsigned int debug_flags = 0;
-struct thread_master *master;
+struct event_loop *master;
struct timeval current_time;
/* nhrpd options. */
#include <sys/types.h>
#include <sys/socket.h>
-#include "thread.h"
+#include "frrevent.h"
#include "nhrpd.h"
#include "netlink.h"
#include "znl.h"
int netlink_mcast_nflog_group;
static int netlink_mcast_log_fd = -1;
-static struct thread *netlink_mcast_log_thread;
+static struct event *netlink_mcast_log_thread;
struct mcast_ctx {
struct interface *ifp;
}
}
-static void netlink_mcast_log_recv(struct thread *t)
+static void netlink_mcast_log_recv(struct event *t)
{
uint8_t buf[65535]; /* Max OSPF Packet size */
- int fd = THREAD_FD(t);
+ int fd = EVENT_FD(t);
struct zbuf payload, zb;
struct nlmsghdr *n;
}
}
- thread_add_read(master, netlink_mcast_log_recv, 0, netlink_mcast_log_fd,
- &netlink_mcast_log_thread);
+ event_add_read(master, netlink_mcast_log_recv, 0, netlink_mcast_log_fd,
+ &netlink_mcast_log_thread);
}
static void netlink_mcast_log_register(int fd, int group)
void netlink_mcast_set_nflog_group(int nlgroup)
{
if (netlink_mcast_log_fd >= 0) {
- THREAD_OFF(netlink_mcast_log_thread);
+ EVENT_OFF(netlink_mcast_log_thread);
close(netlink_mcast_log_fd);
netlink_mcast_log_fd = -1;
debugf(NHRP_DEBUG_COMMON, "De-register nflog group");
return;
netlink_mcast_log_register(netlink_mcast_log_fd, nlgroup);
- thread_add_read(master, netlink_mcast_log_recv, 0,
- netlink_mcast_log_fd,
- &netlink_mcast_log_thread);
+ event_add_read(master, netlink_mcast_log_recv, 0,
+ netlink_mcast_log_fd, &netlink_mcast_log_thread);
debugf(NHRP_DEBUG_COMMON, "Register nflog group: %d",
netlink_mcast_nflog_group);
}
#include "zebra.h"
#include "zbuf.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "nhrpd.h"
#include "nhrp_protocol.h"
DEFINE_MTYPE_STATIC(NHRPD, NHRP_NHS, "NHRP next hop server");
DEFINE_MTYPE_STATIC(NHRPD, NHRP_REGISTRATION, "NHRP registration entries");
-static void nhrp_nhs_resolve(struct thread *t);
-static void nhrp_reg_send_req(struct thread *t);
+static void nhrp_nhs_resolve(struct event *t);
+static void nhrp_reg_send_req(struct event *t);
static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg)
{
/* Success - schedule next registration, and route NHS */
r->timeout = 2;
holdtime = nifp->afi[nhs->afi].holdtime;
- THREAD_OFF(r->t_register);
+ EVENT_OFF(r->t_register);
/* RFC 2332 5.2.3 - Registration is recommend to be renewed
* every one third of holdtime */
- thread_add_timer(master, nhrp_reg_send_req, r, holdtime / 3,
- &r->t_register);
+ event_add_timer(master, nhrp_reg_send_req, r, holdtime / 3,
+ &r->t_register);
r->proto_addr = p->dst_proto;
c = nhrp_cache_get(ifp, &p->dst_proto, 1);
&cie_nbma_nhs);
}
-static void nhrp_reg_timeout(struct thread *t)
+static void nhrp_reg_timeout(struct event *t)
{
- struct nhrp_registration *r = THREAD_ARG(t);
+ struct nhrp_registration *r = EVENT_ARG(t);
struct nhrp_cache *c;
}
r->timeout = 2;
}
- thread_add_timer_msec(master, nhrp_reg_send_req, r, 10, &r->t_register);
+ event_add_timer_msec(master, nhrp_reg_send_req, r, 10, &r->t_register);
}
static void nhrp_reg_peer_notify(struct notifier_block *n, unsigned long cmd)
case NOTIFY_PEER_MTU_CHANGED:
debugf(NHRP_DEBUG_COMMON, "NHS: Flush timer for %pSU",
&r->peer->vc->remote.nbma);
- THREAD_OFF(r->t_register);
- thread_add_timer_msec(master, nhrp_reg_send_req, r, 10,
- &r->t_register);
+ EVENT_OFF(r->t_register);
+ event_add_timer_msec(master, nhrp_reg_send_req, r, 10,
+ &r->t_register);
break;
}
}
-static void nhrp_reg_send_req(struct thread *t)
+static void nhrp_reg_send_req(struct event *t)
{
- struct nhrp_registration *r = THREAD_ARG(t);
+ struct nhrp_registration *r = EVENT_ARG(t);
struct nhrp_nhs *nhs = r->nhs;
struct interface *ifp = nhs->ifp;
struct nhrp_interface *nifp = ifp->info;
if (!nhrp_peer_check(r->peer, 2)) {
debugf(NHRP_DEBUG_COMMON, "NHS: Waiting link for %pSU",
&r->peer->vc->remote.nbma);
- thread_add_timer(master, nhrp_reg_send_req, r, 120,
- &r->t_register);
+ event_add_timer(master, nhrp_reg_send_req, r, 120,
+ &r->t_register);
return;
}
- thread_add_timer(master, nhrp_reg_timeout, r, r->timeout,
- &r->t_register);
+ event_add_timer(master, nhrp_reg_timeout, r, r->timeout,
+ &r->t_register);
/* RFC2332 5.2.3 NHC uses it's own address as dst if NHS is unknown */
dst_proto = &nhs->proto_addr;
nhrp_peer_notify_del(r->peer, &r->peer_notifier);
nhrp_peer_unref(r->peer);
nhrp_reglist_del(&r->nhs->reglist_head, r);
- THREAD_OFF(r->t_register);
+ EVENT_OFF(r->t_register);
XFREE(MTYPE_NHRP_REGISTRATION, r);
}
if (n < 0) {
/* Failed, retry in a moment */
- thread_add_timer(master, nhrp_nhs_resolve, nhs, 5,
- &nhs->t_resolve);
+ event_add_timer(master, nhrp_nhs_resolve, nhs, 5,
+ &nhs->t_resolve);
return;
}
- thread_add_timer(master, nhrp_nhs_resolve, nhs, 2 * 60 * 60,
- &nhs->t_resolve);
+ event_add_timer(master, nhrp_nhs_resolve, nhs, 2 * 60 * 60,
+ &nhs->t_resolve);
frr_each (nhrp_reglist, &nhs->reglist_head, reg)
reg->mark = 1;
nhrp_reglist_add_tail(&nhs->reglist_head, reg);
nhrp_peer_notify_add(reg->peer, ®->peer_notifier,
nhrp_reg_peer_notify);
- thread_add_timer_msec(master, nhrp_reg_send_req, reg, 50,
- ®->t_register);
+ event_add_timer_msec(master, nhrp_reg_send_req, reg, 50,
+ ®->t_register);
}
frr_each_safe (nhrp_reglist, &nhs->reglist_head, reg)
nhrp_reg_delete(reg);
}
-static void nhrp_nhs_resolve(struct thread *t)
+static void nhrp_nhs_resolve(struct event *t)
{
- struct nhrp_nhs *nhs = THREAD_ARG(t);
+ struct nhrp_nhs *nhs = EVENT_ARG(t);
resolver_resolve(&nhs->dns_resolve, AF_INET, VRF_DEFAULT,
nhs->nbma_fqdn, nhrp_nhs_resolve_cb);
.reglist_head = INIT_DLIST(nhs->reglist_head),
};
nhrp_nhslist_add_tail(&nifp->afi[afi].nhslist_head, nhs);
- thread_add_timer_msec(master, nhrp_nhs_resolve, nhs, 1000,
- &nhs->t_resolve);
+ event_add_timer_msec(master, nhrp_nhs_resolve, nhs, 1000,
+ &nhs->t_resolve);
return NHRP_OK;
}
frr_each_safe (nhrp_reglist, &nhs->reglist_head, r)
nhrp_reg_delete(r);
- THREAD_OFF(nhs->t_resolve);
+ EVENT_OFF(nhs->t_resolve);
nhrp_nhslist_del(&nifp->afi[afi].nhslist_head, nhs);
free((void *)nhs->nbma_fqdn);
XFREE(MTYPE_NHRP_NHS, nhs);
#include <netinet/if_ether.h>
#include "nhrpd.h"
#include "zbuf.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "nhrp_protocol.h"
return -1;
}
-static void nhrp_packet_recvraw(struct thread *t)
+static void nhrp_packet_recvraw(struct event *t)
{
- int fd = THREAD_FD(t), ifindex;
+ int fd = EVENT_FD(t), ifindex;
struct zbuf *zb;
struct interface *ifp;
struct nhrp_peer *p;
uint8_t addr[64];
size_t len, addrlen;
- thread_add_read(master, nhrp_packet_recvraw, 0, fd, NULL);
+ event_add_read(master, nhrp_packet_recvraw, 0, fd, NULL);
zb = zbuf_alloc(1500);
if (!zb)
int nhrp_packet_init(void)
{
- thread_add_read(master, nhrp_packet_recvraw, 0, os_socket(), NULL);
+ event_add_read(master, nhrp_packet_recvraw, 0, os_socket(), NULL);
return 0;
}
#include "zebra.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "network.h"
debugf(NHRP_DEBUG_COMMON, "Deleting peer ref:%d remote:%pSU local:%pSU",
p->ref, &p->vc->remote.nbma, &p->vc->local.nbma);
- THREAD_OFF(p->t_fallback);
- THREAD_OFF(p->t_timer);
+ EVENT_OFF(p->t_fallback);
+ EVENT_OFF(p->t_timer);
hash_release(nifp->peer_hash, p);
nhrp_interface_notify_del(p->ifp, &p->ifp_notifier);
nhrp_vc_notify_del(p->vc, &p->vc_notifier);
XFREE(MTYPE_NHRP_PEER, p);
}
-static void nhrp_peer_notify_up(struct thread *t)
+static void nhrp_peer_notify_up(struct event *t)
{
- struct nhrp_peer *p = THREAD_ARG(t);
+ struct nhrp_peer *p = EVENT_ARG(t);
struct nhrp_vc *vc = p->vc;
struct interface *ifp = p->ifp;
struct nhrp_interface *nifp = ifp->info;
online = nifp->enabled && (!nifp->ipsec_profile || vc->ipsec);
if (p->online != online) {
- THREAD_OFF(p->t_fallback);
+ EVENT_OFF(p->t_fallback);
if (online && notifier_active(&p->notifier_list)) {
/* If we requested the IPsec connection, delay
* the up notification a bit to allow things
* settle down. This allows IKE to install
* SPDs and SAs. */
- thread_add_timer_msec(master, nhrp_peer_notify_up, p,
- 50, &p->t_fallback);
+ event_add_timer_msec(master, nhrp_peer_notify_up, p, 50,
+ &p->t_fallback);
} else {
nhrp_peer_ref(p);
p->online = online;
debugf(NHRP_DEBUG_COMMON, "Cleaning up undeleted peer entries (%lu)",
nifp->peer_hash ? nifp->peer_hash->count : 0);
- if (nifp->peer_hash) {
- hash_clean(nifp->peer_hash, do_peer_hash_free);
- assert(nifp->peer_hash->count == 0);
- hash_free(nifp->peer_hash);
- nifp->peer_hash = NULL;
- }
+ hash_clean_and_free(&nifp->peer_hash, do_peer_hash_free);
}
struct nhrp_peer *nhrp_peer_get(struct interface *ifp,
}
}
-static void nhrp_peer_request_timeout(struct thread *t)
+static void nhrp_peer_request_timeout(struct event *t)
{
- struct nhrp_peer *p = THREAD_ARG(t);
+ struct nhrp_peer *p = EVENT_ARG(t);
struct nhrp_vc *vc = p->vc;
struct interface *ifp = p->ifp;
struct nhrp_interface *nifp = ifp->info;
p->fallback_requested = 1;
vici_request_vc(nifp->ipsec_fallback_profile, &vc->local.nbma,
&vc->remote.nbma, p->prio);
- thread_add_timer(master, nhrp_peer_request_timeout, p, 30,
- &p->t_fallback);
+ event_add_timer(master, nhrp_peer_request_timeout, p, 30,
+ &p->t_fallback);
} else {
p->requested = p->fallback_requested = 0;
}
}
-static void nhrp_peer_defer_vici_request(struct thread *t)
+static void nhrp_peer_defer_vici_request(struct event *t)
{
- struct nhrp_peer *p = THREAD_ARG(t);
+ struct nhrp_peer *p = EVENT_ARG(t);
struct nhrp_vc *vc = p->vc;
struct interface *ifp = p->ifp;
struct nhrp_interface *nifp = ifp->info;
- THREAD_OFF(p->t_timer);
+ EVENT_OFF(p->t_timer);
if (p->online) {
debugf(NHRP_DEBUG_COMMON,
} else {
vici_request_vc(nifp->ipsec_profile, &vc->local.nbma,
&vc->remote.nbma, p->prio);
- thread_add_timer(
- master, nhrp_peer_request_timeout, p,
- (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
- &p->t_fallback);
+ event_add_timer(master, nhrp_peer_request_timeout, p,
+ (nifp->ipsec_fallback_profile && !p->prio) ? 15
+ : 30,
+ &p->t_fallback);
}
}
if (p->prio) {
vici_request_vc(nifp->ipsec_profile, &vc->local.nbma,
&vc->remote.nbma, p->prio);
- thread_add_timer(
- master, nhrp_peer_request_timeout, p,
- (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
- &p->t_fallback);
+ event_add_timer(master, nhrp_peer_request_timeout, p,
+ (nifp->ipsec_fallback_profile && !p->prio) ? 15
+ : 30,
+ &p->t_fallback);
} else {
/* Maximum timeout is 1 second */
int r_time_ms = frr_weak_random() % 1000;
debugf(NHRP_DEBUG_COMMON,
"Initiating IPsec connection request to %pSU after %d ms:",
&vc->remote.nbma, r_time_ms);
- thread_add_timer_msec(master, nhrp_peer_defer_vici_request,
- p, r_time_ms, &p->t_timer);
+ event_add_timer_msec(master, nhrp_peer_defer_vici_request, p,
+ r_time_ms, &p->t_timer);
}
return 0;
#include "nhrpd.h"
#include "table.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "nhrp_protocol.h"
static struct route_table *shortcut_rib[AFI_MAX];
-static void nhrp_shortcut_do_purge(struct thread *t);
+static void nhrp_shortcut_do_purge(struct event *t);
static void nhrp_shortcut_delete(struct nhrp_shortcut *s);
static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s);
}
}
-static void nhrp_shortcut_do_expire(struct thread *t)
+static void nhrp_shortcut_do_expire(struct event *t)
{
- struct nhrp_shortcut *s = THREAD_ARG(t);
+ struct nhrp_shortcut *s = EVENT_ARG(t);
- thread_add_timer(master, nhrp_shortcut_do_purge, s, s->holding_time / 3,
- &s->t_timer);
+ event_add_timer(master, nhrp_shortcut_do_purge, s, s->holding_time / 3,
+ &s->t_timer);
s->expiring = 1;
nhrp_shortcut_check_use(s);
}
s->route_installed = 0;
}
- THREAD_OFF(s->t_timer);
+ EVENT_OFF(s->t_timer);
if (holding_time) {
s->expiring = 0;
s->holding_time = holding_time;
- thread_add_timer(master, nhrp_shortcut_do_expire, s,
- 2 * holding_time / 3, &s->t_timer);
+ event_add_timer(master, nhrp_shortcut_do_expire, s,
+ 2 * holding_time / 3, &s->t_timer);
}
}
struct route_node *rn;
afi_t afi = family2afi(PREFIX_FAMILY(s->p));
- THREAD_OFF(s->t_timer);
+ EVENT_OFF(s->t_timer);
nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX purged", s->p);
}
}
-static void nhrp_shortcut_do_purge(struct thread *t)
+static void nhrp_shortcut_do_purge(struct event *t)
{
- struct nhrp_shortcut *s = THREAD_ARG(t);
+ struct nhrp_shortcut *s = EVENT_ARG(t);
s->t_timer = NULL;
nhrp_shortcut_delete(s);
}
int holding_time = pp->if_ad->holdtime;
nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
- THREAD_OFF(s->t_timer);
- thread_add_timer(master, nhrp_shortcut_do_purge, s, 1, &s->t_timer);
+ EVENT_OFF(s->t_timer);
+ event_add_timer(master, nhrp_shortcut_do_purge, s, 1, &s->t_timer);
if (pp->hdr->type != NHRP_PACKET_RESOLUTION_REPLY) {
if (pp->hdr->type == NHRP_PACKET_ERROR_INDICATION
s = nhrp_shortcut_get(&p);
if (s && s->type != NHRP_CACHE_INCOMPLETE) {
s->addr = *addr;
- THREAD_OFF(s->t_timer);
- thread_add_timer(master, nhrp_shortcut_do_purge, s, 30,
- &s->t_timer);
+ EVENT_OFF(s->t_timer);
+ event_add_timer(master, nhrp_shortcut_do_purge, s, 30,
+ &s->t_timer);
nhrp_shortcut_send_resolution_req(s);
}
}
void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force)
{
- THREAD_OFF(s->t_timer);
+ EVENT_OFF(s->t_timer);
nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
if (force) {
/* Immediate purge on route with draw or pending shortcut */
- thread_add_timer_msec(master, nhrp_shortcut_do_purge, s, 5,
- &s->t_timer);
+ event_add_timer_msec(master, nhrp_shortcut_do_purge, s, 5,
+ &s->t_timer);
} else {
/* Soft expire - force immediate renewal, but purge
* in few seconds to make sure stale route is not
* This allows to keep nhrp route up, and to not
* cause temporary rerouting via hubs causing latency
* jitter. */
- thread_add_timer_msec(master, nhrp_shortcut_do_purge, s, 3000,
- &s->t_timer);
+ event_add_timer_msec(master, nhrp_shortcut_do_purge, s, 3000,
+ &s->t_timer);
s->expiring = 1;
nhrp_shortcut_check_use(s);
}
#include "memory.h"
#include "stream.h"
#include "hash.h"
-#include "thread.h"
+#include "frrevent.h"
#include "jhash.h"
#include "nhrpd.h"
#define NHRP_VTY_PORT 2610
#define NHRP_DEFAULT_CONFIG "nhrpd.conf"
-extern struct thread_master *master;
+extern struct event_loop *master;
enum { NHRP_OK = 0,
NHRP_ERR_FAIL,
struct notifier_list notifier_list;
struct interface *ifp;
struct nhrp_vc *vc;
- struct thread *t_fallback;
+ struct event *t_fallback;
struct notifier_block vc_notifier, ifp_notifier;
- struct thread *t_timer;
+ struct event *t_timer;
};
struct nhrp_packet_parser {
struct notifier_block newpeer_notifier;
struct notifier_list notifier_list;
struct nhrp_reqid eventid;
- struct thread *t_timeout;
- struct thread *t_auth;
+ struct event *t_timeout;
+ struct event *t_auth;
struct {
enum nhrp_cache_type type;
union sockunion addr;
struct nhrp_reqid reqid;
- struct thread *t_timer;
+ struct event *t_timer;
enum nhrp_cache_type type;
unsigned int holding_time;
union sockunion proto_addr;
const char *nbma_fqdn; /* IP-address or FQDN */
- struct thread *t_resolve;
+ struct event *t_resolve;
struct resolver_query dns_resolve;
struct nhrp_reglist_head reglist_head;
};
struct nhrp_registration {
struct nhrp_reglist_item reglist_entry;
- struct thread *t_register;
+ struct event *t_register;
struct nhrp_nhs *nhs;
struct nhrp_reqid reqid;
unsigned int timeout;
#include <sys/socket.h>
#include <sys/un.h>
-#include "thread.h"
+#include "frrevent.h"
#include "zbuf.h"
#include "log.h"
#include "lib_errors.h"
}
struct vici_conn {
- struct thread *t_reconnect, *t_read, *t_write;
+ struct event *t_reconnect, *t_read, *t_write;
struct zbuf ibuf;
struct zbuf_queue obuf;
int fd;
int nsections;
};
-static void vici_reconnect(struct thread *t);
+static void vici_reconnect(struct event *t);
static void vici_submit_request(struct vici_conn *vici, const char *name, ...);
static void vici_zbuf_puts(struct zbuf *obuf, const char *str)
{
nhrp_vc_reset();
- THREAD_OFF(vici->t_read);
- THREAD_OFF(vici->t_write);
+ EVENT_OFF(vici->t_read);
+ EVENT_OFF(vici->t_write);
zbuf_reset(&vici->ibuf);
zbufq_reset(&vici->obuf);
close(vici->fd);
vici->fd = -1;
- thread_add_timer(master, vici_reconnect, vici, 2, &vici->t_reconnect);
+ event_add_timer(master, vici_reconnect, vici, 2, &vici->t_reconnect);
}
static void vici_parse_message(struct vici_conn *vici, struct zbuf *msg,
}
}
-static void vici_read(struct thread *t)
+static void vici_read(struct event *t)
{
- struct vici_conn *vici = THREAD_ARG(t);
+ struct vici_conn *vici = EVENT_ARG(t);
struct zbuf *ibuf = &vici->ibuf;
struct zbuf pktbuf;
vici_recv_message(vici, &pktbuf);
} while (1);
- thread_add_read(master, vici_read, vici, vici->fd, &vici->t_read);
+ event_add_read(master, vici_read, vici, vici->fd, &vici->t_read);
}
-static void vici_write(struct thread *t)
+static void vici_write(struct event *t)
{
- struct vici_conn *vici = THREAD_ARG(t);
+ struct vici_conn *vici = EVENT_ARG(t);
int r;
r = zbufq_write(&vici->obuf, vici->fd);
if (r > 0) {
- thread_add_write(master, vici_write, vici, vici->fd,
- &vici->t_write);
+ event_add_write(master, vici_write, vici, vici->fd,
+ &vici->t_write);
} else if (r < 0) {
vici_connection_error(vici);
}
}
zbufq_queue(&vici->obuf, obuf);
- thread_add_write(master, vici_write, vici, vici->fd, &vici->t_write);
+ event_add_write(master, vici_write, vici, vici->fd, &vici->t_write);
}
static void vici_submit_request(struct vici_conn *vici, const char *name, ...)
return buff;
}
-static void vici_reconnect(struct thread *t)
+static void vici_reconnect(struct event *t)
{
- struct vici_conn *vici = THREAD_ARG(t);
+ struct vici_conn *vici = EVENT_ARG(t);
int fd;
char *file_path;
debugf(NHRP_DEBUG_VICI,
"%s: failure connecting VICI socket: %s", __func__,
strerror(errno));
- thread_add_timer(master, vici_reconnect, vici, 2,
- &vici->t_reconnect);
+ event_add_timer(master, vici_reconnect, vici, 2,
+ &vici->t_reconnect);
return;
}
debugf(NHRP_DEBUG_COMMON, "VICI: Connected");
vici->fd = fd;
- thread_add_read(master, vici_read, vici, vici->fd, &vici->t_read);
+ event_add_read(master, vici_read, vici, vici->fd, &vici->t_read);
/* Send event subscribtions */
// vici_register_event(vici, "child-updown");
vici->fd = -1;
zbuf_init(&vici->ibuf, vici->ibuf_data, sizeof(vici->ibuf_data), 0);
zbufq_init(&vici->obuf);
- thread_add_timer_msec(master, vici_reconnect, vici, 10,
- &vici->t_reconnect);
+ event_add_timer_msec(master, vici_reconnect, vici, 10,
+ &vici->t_reconnect);
}
void vici_terminate(void)
#include "vty.h"
#include "linklist.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "plist.h"
#include "filter.h"
#include "log.h"
#include "memory.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "if.h"
ospf6_spf_table_finish(oa->spf_table);
ospf6_route_remove_all(oa->route_table);
- THREAD_OFF(oa->thread_router_lsa);
- THREAD_OFF(oa->thread_intra_prefix_lsa);
+ EVENT_OFF(oa->thread_router_lsa);
+ EVENT_OFF(oa->thread_intra_prefix_lsa);
}
uint32_t spf_calculation; /* SPF calculation count */
- struct thread *thread_router_lsa;
- struct thread *thread_intra_prefix_lsa;
+ struct event *thread_router_lsa;
+ struct event *thread_intra_prefix_lsa;
uint32_t router_lsa_size_limit;
/* Area announce list */
#include "routemap.h"
#include "table.h"
#include "plist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "lib/northbound_cli.h"
return lsa;
}
-void ospf6_orig_as_external_lsa(struct thread *thread)
+void ospf6_orig_as_external_lsa(struct event *thread)
{
struct ospf6_interface *oi;
struct ospf6_lsa *lsa;
uint32_t type, adv_router;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
if (oi->state == OSPF6_INTERFACE_DOWN)
return;
ROUTEMAP(red) = NULL;
}
-static void ospf6_asbr_routemap_update_timer(struct thread *thread)
+static void ospf6_asbr_routemap_update_timer(struct event *thread)
{
- struct ospf6 *ospf6 = THREAD_ARG(thread);
+ struct ospf6 *ospf6 = EVENT_ARG(thread);
struct ospf6_redist *red;
int type;
{
SET_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED);
- if (thread_is_scheduled(ospf6->t_distribute_update))
+ if (event_is_scheduled(ospf6->t_distribute_update))
return;
if (IS_OSPF6_DEBUG_ASBR)
zlog_debug("%s: trigger redistribute reset thread", __func__);
- thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer, ospf6,
- OSPF_MIN_LS_INTERVAL,
- &ospf6->t_distribute_update);
+ event_add_timer_msec(master, ospf6_asbr_routemap_update_timer, ospf6,
+ OSPF_MIN_LS_INTERVAL, &ospf6->t_distribute_update);
}
void ospf6_asbr_routemap_update(const char *mapname)
if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: LSA found, refresh it",
__func__);
- THREAD_OFF(lsa->refresh);
- thread_add_event(master, ospf6_lsa_refresh, lsa, 0,
- &lsa->refresh);
+ EVENT_OFF(lsa->refresh);
+ event_add_event(master, ospf6_lsa_refresh, lsa, 0,
+ &lsa->refresh);
return;
}
}
aggr->action = OSPF6_ROUTE_AGGR_NONE;
ospf6_asbr_summary_config_delete(ospf6, rn);
- if (OSPF6_EXTERNAL_RT_COUNT(aggr))
- hash_clean(aggr->match_extnl_hash,
- ospf6_aggr_handle_external_info);
+ hash_clean_and_free(&aggr->match_extnl_hash,
+ ospf6_aggr_handle_external_info);
- hash_free(aggr->match_extnl_hash);
XFREE(MTYPE_OSPF6_EXTERNAL_RT_AGGR, aggr);
} else if (aggr->action == OSPF6_ROUTE_AGGR_MODIFY) {
void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr)
{
- if (OSPF6_EXTERNAL_RT_COUNT(aggr))
- hash_clean(aggr->match_extnl_hash,
- ospf6_aggr_unlink_external_info);
+ hash_clean_and_free(&aggr->match_extnl_hash,
+ ospf6_aggr_unlink_external_info);
if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Release the aggregator Address(%pFX)",
__func__,
&aggr->p);
- hash_free(aggr->match_extnl_hash);
- aggr->match_extnl_hash = NULL;
-
XFREE(MTYPE_OSPF6_EXTERNAL_RT_AGGR, aggr);
}
lsa = ospf6_find_external_lsa(ospf6, &rt->prefix);
if (lsa) {
- THREAD_OFF(lsa->refresh);
- thread_add_event(master, ospf6_lsa_refresh, lsa, 0,
- &lsa->refresh);
+ EVENT_OFF(lsa->refresh);
+ event_add_event(master, ospf6_lsa_refresh, lsa, 0,
+ &lsa->refresh);
} else {
if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Originate external route(%pFX)",
}
}
-static void ospf6_asbr_summary_process(struct thread *thread)
+static void ospf6_asbr_summary_process(struct event *thread)
{
- struct ospf6 *ospf6 = THREAD_ARG(thread);
+ struct ospf6 *ospf6 = EVENT_ARG(thread);
int operation = 0;
operation = ospf6->aggr_action;
{
aggr->action = operation;
- if (thread_is_scheduled(ospf6->t_external_aggr)) {
+ if (event_is_scheduled(ospf6->t_external_aggr)) {
if (ospf6->aggr_action == OSPF6_ROUTE_AGGR_ADD) {
if (IS_OSPF6_DEBUG_AGGR)
if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s, Restarting Aggregator delay timer.",
__func__);
- THREAD_OFF(ospf6->t_external_aggr);
+ EVENT_OFF(ospf6->t_external_aggr);
}
}
__func__, ospf6->aggr_delay_interval);
ospf6->aggr_action = operation;
- thread_add_timer(master,
- ospf6_asbr_summary_process,
- ospf6, ospf6->aggr_delay_interval,
- &ospf6->t_external_aggr);
+ event_add_timer(master, ospf6_asbr_summary_process, ospf6,
+ ospf6->aggr_delay_interval, &ospf6->t_external_aggr);
}
int ospf6_asbr_external_rt_advertise(struct ospf6 *ospf6,
#include "linklist.h"
#include "memory.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "stream.h"
#include "zclient.h"
if (bss->state == BFD_STATUS_DOWN
&& bss->previous_state == BFD_STATUS_UP) {
- THREAD_OFF(on->inactivity_timer);
- thread_add_event(master, inactivity_timer, on, 0, NULL);
+ EVENT_OFF(on->inactivity_timer);
+ event_add_event(master, inactivity_timer, on, 0, NULL);
}
}
#include <zebra.h>
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "command.h"
lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self);
- THREAD_OFF(lsa->refresh);
- thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
- &lsa->refresh);
+ EVENT_OFF(lsa->refresh);
+ event_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
+ &lsa->refresh);
if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
|| IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) {
self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
lsa->header->adv_router, lsdb_self);
if (self) {
- THREAD_OFF(self->expire);
- THREAD_OFF(self->refresh);
+ EVENT_OFF(self->expire);
+ EVENT_OFF(self->refresh);
ospf6_lsdb_remove(self, lsdb_self);
}
lsa->name);
lsa->external_lsa_id = old->external_lsa_id;
}
- THREAD_OFF(old->expire);
- THREAD_OFF(old->refresh);
+ EVENT_OFF(old->expire);
+ EVENT_OFF(old->refresh);
ospf6_flood_clear(old);
}
monotime(&now);
if (!OSPF6_LSA_IS_MAXAGE(lsa)) {
- thread_add_timer(master, ospf6_lsa_expire, lsa,
- OSPF_LSA_MAXAGE + lsa->birth.tv_sec
- - now.tv_sec,
- &lsa->expire);
+ event_add_timer(master, ospf6_lsa_expire, lsa,
+ OSPF_LSA_MAXAGE + lsa->birth.tv_sec -
+ now.tv_sec,
+ &lsa->expire);
} else
lsa->expire = NULL;
ospf6_lsdb_add(ospf6_lsa_copy(lsa),
on->retrans_list);
- thread_add_timer(
- master, ospf6_lsupdate_send_neighbor,
- on, on->ospf6_if->rxmt_interval,
- &on->thread_send_lsupdate);
+ event_add_timer(master,
+ ospf6_lsupdate_send_neighbor,
+ on, on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsupdate);
retrans_added++;
}
}
if ((oi->type == OSPF_IFTYPE_BROADCAST)
|| (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list);
- thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
- &oi->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
+ &oi->thread_send_lsupdate);
} else {
/* reschedule retransmissions to all neighbors */
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
- THREAD_OFF(on->thread_send_lsupdate);
- thread_add_event(master, ospf6_lsupdate_send_neighbor,
- on, 0, &on->thread_send_lsupdate);
+ EVENT_OFF(on->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_neighbor,
+ on, 0, &on->thread_send_lsupdate);
}
}
}
"Delayed acknowledgement (BDR & MoreRecent & from DR)");
/* Delayed acknowledgement */
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
- thread_add_timer(master, ospf6_lsack_send_interface, oi,
- 3, &oi->thread_send_lsack);
+ event_add_timer(master, ospf6_lsack_send_interface, oi,
+ 3, &oi->thread_send_lsack);
} else {
if (is_debug)
zlog_debug(
"Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
/* Delayed acknowledgement */
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
- thread_add_timer(master, ospf6_lsack_send_interface, oi,
- 3, &oi->thread_send_lsack);
+ event_add_timer(master, ospf6_lsack_send_interface, oi,
+ 3, &oi->thread_send_lsack);
} else {
if (is_debug)
zlog_debug(
if (is_debug)
zlog_debug("Direct acknowledgement (BDR & Duplicate)");
ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
- thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
- &from->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
return;
}
"Delayed acknowledgement (AllOther & MoreRecent)");
/* Delayed acknowledgement */
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
- thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
- &oi->thread_send_lsack);
+ event_add_timer(master, ospf6_lsack_send_interface, oi, 3,
+ &oi->thread_send_lsack);
return;
}
zlog_debug(
"Direct acknowledgement (AllOther & Duplicate)");
ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
- thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
- &from->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
return;
}
/* a) Acknowledge back to neighbor (Direct acknowledgement,
* 13.5) */
ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list);
- thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
- &from->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
/* b) Discard */
ospf6_lsa_delete(new);
"Newer instance of the self-originated LSA");
zlog_debug("Schedule reorigination");
}
- thread_add_event(master, ospf6_lsa_refresh, new, 0,
- &new->refresh);
+ event_add_event(master, ospf6_lsa_refresh, new, 0,
+ &new->refresh);
}
/* GR: check for network topology change. */
new->name);
/* BadLSReq */
- thread_add_event(master, bad_lsreq, from, 0, NULL);
+ event_add_event(master, bad_lsreq, from, 0, NULL);
ospf6_lsa_delete(new);
return;
ospf6_lsdb_add(ospf6_lsa_copy(old),
from->lsupdate_list);
- thread_add_event(master, ospf6_lsupdate_send_neighbor,
- from, 0, &from->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_neighbor,
+ from, 0, &from->thread_send_lsupdate);
ospf6_lsa_delete(new);
return;
ospf6->gr_info.restart_in_progress = false;
ospf6->gr_info.finishing_restart = true;
- THREAD_OFF(ospf6->gr_info.t_grace_period);
+ EVENT_OFF(ospf6->gr_info.t_grace_period);
/* Record in non-volatile memory that the restart is complete. */
ospf6_gr_nvm_delete(ospf6);
}
/* Handling of grace period expiry. */
-static void ospf6_gr_grace_period_expired(struct thread *thread)
+static void ospf6_gr_grace_period_expired(struct event *thread)
{
- struct ospf6 *ospf6 = THREAD_ARG(thread);
+ struct ospf6 *ospf6 = EVENT_ARG(thread);
ospf6_gr_restart_exit(ospf6, "grace period has expired");
}
zlog_debug(
"GR: remaining time until grace period expires: %lu(s)",
remaining_time);
- thread_add_timer(master, ospf6_gr_grace_period_expired,
- ospf6, remaining_time,
- &ospf6->gr_info.t_grace_period);
+ event_add_timer(master, ospf6_gr_grace_period_expired,
+ ospf6, remaining_time,
+ &ospf6->gr_info.t_grace_period);
}
}
if (ospf6->ospf6_helper_cfg.enable_rtr_list == NULL)
return;
- hash_clean(ospf6->ospf6_helper_cfg.enable_rtr_list,
- ospf6_disable_rtr_hash_free);
- hash_free(ospf6->ospf6_helper_cfg.enable_rtr_list);
- ospf6->ospf6_helper_cfg.enable_rtr_list = NULL;
+ hash_clean_and_free(&ospf6->ospf6_helper_cfg.enable_rtr_list,
+ ospf6_disable_rtr_hash_free);
}
/*
* Returns:
* Nothing
*/
-static void ospf6_handle_grace_timer_expiry(struct thread *thread)
+static void ospf6_handle_grace_timer_expiry(struct event *thread)
{
- struct ospf6_neighbor *nbr = THREAD_ARG(thread);
+ struct ospf6_neighbor *nbr = EVENT_ARG(thread);
ospf6_gr_helper_exit(nbr, OSPF6_GR_HELPER_GRACE_TIMEOUT);
}
}
if (OSPF6_GR_IS_ACTIVE_HELPER(restarter)) {
- THREAD_OFF(restarter->gr_helper_info.t_grace_timer);
+ EVENT_OFF(restarter->gr_helper_info.t_grace_timer);
if (ospf6->ospf6_helper_cfg.active_restarter_cnt > 0)
ospf6->ospf6_helper_cfg.active_restarter_cnt--;
actual_grace_interval);
/* Start the grace timer */
- thread_add_timer(master, ospf6_handle_grace_timer_expiry, restarter,
- actual_grace_interval,
- &restarter->gr_helper_info.t_grace_timer);
+ event_add_timer(master, ospf6_handle_grace_timer_expiry, restarter,
+ actual_grace_interval,
+ &restarter->gr_helper_info.t_grace_timer);
return OSPF6_GR_ACTIVE_HELPER;
}
* expiry, stop the grace timer.
*/
if (reason != OSPF6_GR_HELPER_GRACE_TIMEOUT)
- THREAD_OFF(nbr->gr_helper_info.t_grace_timer);
+ EVENT_OFF(nbr->gr_helper_info.t_grace_timer);
if (ospf6->ospf6_helper_cfg.active_restarter_cnt <= 0) {
zlog_err(
vty_out(vty, " Actual Grace period : %d(in seconds)\n",
nbr->gr_helper_info.actual_grace_period);
vty_out(vty, " Remaining GraceTime:%ld(in seconds).\n",
- thread_timer_remain_second(
+ event_timer_remain_second(
nbr->gr_helper_info.t_grace_timer));
vty_out(vty, " Graceful Restart reason: %s.\n\n",
ospf6_restart_reason_desc[nbr->gr_helper_info
json_object_int_add(json_neigh, "actualGraceInterval",
nbr->gr_helper_info.actual_grace_period);
json_object_int_add(json_neigh, "remainGracetime",
- thread_timer_remain_second(
- nbr->gr_helper_info.t_grace_timer));
+ event_timer_remain_second(
+ nbr->gr_helper_info.t_grace_timer));
json_object_string_add(json_neigh, "restartReason",
ospf6_restart_reason_desc[
nbr->gr_helper_info.gr_restart_reason]);
#include "if.h"
#include "log.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "plist.h"
#include "zclient.h"
list_delete(&oi->neighbor_list);
- THREAD_OFF(oi->thread_send_hello);
- THREAD_OFF(oi->thread_send_lsupdate);
- THREAD_OFF(oi->thread_send_lsack);
- THREAD_OFF(oi->thread_sso);
- THREAD_OFF(oi->thread_wait_timer);
+ EVENT_OFF(oi->thread_send_hello);
+ EVENT_OFF(oi->thread_send_lsupdate);
+ EVENT_OFF(oi->thread_send_lsack);
+ EVENT_OFF(oi->thread_sso);
+ EVENT_OFF(oi->thread_wait_timer);
ospf6_lsdb_remove_all(oi->lsdb);
ospf6_lsdb_remove_all(oi->lsupdate_list);
{
SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE);
- thread_execute(master, interface_down, oi, 0);
+ event_execute(master, interface_down, oi, 0);
ospf6_lsdb_remove_all(oi->lsdb);
ospf6_lsdb_remove_all(oi->lsdb_self);
ospf6_lsdb_remove_all(oi->lsupdate_list);
ospf6_lsdb_remove_all(oi->lsack_list);
- THREAD_OFF(oi->thread_send_hello);
- THREAD_OFF(oi->thread_send_lsupdate);
- THREAD_OFF(oi->thread_send_lsack);
- THREAD_OFF(oi->thread_sso);
+ EVENT_OFF(oi->thread_send_hello);
+ EVENT_OFF(oi->thread_send_lsupdate);
+ EVENT_OFF(oi->thread_send_lsack);
+ EVENT_OFF(oi->thread_sso);
- THREAD_OFF(oi->thread_network_lsa);
- THREAD_OFF(oi->thread_link_lsa);
- THREAD_OFF(oi->thread_intra_prefix_lsa);
- THREAD_OFF(oi->thread_as_extern_lsa);
- THREAD_OFF(oi->thread_wait_timer);
+ EVENT_OFF(oi->thread_network_lsa);
+ EVENT_OFF(oi->thread_link_lsa);
+ EVENT_OFF(oi->thread_intra_prefix_lsa);
+ EVENT_OFF(oi->thread_as_extern_lsa);
+ EVENT_OFF(oi->thread_wait_timer);
}
static struct in6_addr *
if (if_is_operative(ifp)
&& (ospf6_interface_get_linklocal_address(oi->interface)
|| if_is_loopback(oi->interface)))
- thread_execute(master, interface_up, oi, 0);
+ event_execute(master, interface_up, oi, 0);
else
- thread_execute(master, interface_down, oi, 0);
+ event_execute(master, interface_down, oi, 0);
return;
}
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
continue;
/* Schedule AdjOK. */
- thread_add_event(master, adj_ok, on, 0,
- &on->thread_adj_ok);
+ event_add_event(master, adj_ok, on, 0,
+ &on->thread_adj_ok);
}
}
#endif /* __FreeBSD__ */
/* Interface State Machine */
-void interface_up(struct thread *thread)
+void interface_up(struct event *thread)
{
struct ospf6_interface *oi;
struct ospf6 *ospf6;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi && oi->interface);
if (!oi->type_cfg)
oi->type = ospf6_default_iftype(oi->interface);
- thread_cancel(&oi->thread_sso);
+ event_cancel(&oi->thread_sso);
if (IS_OSPF6_DEBUG_INTERFACE)
zlog_debug("Interface Event %s: [InterfaceUp]",
zlog_info(
"Interface %s is still in all routers group, rescheduling for SSO",
oi->interface->name);
- thread_add_timer(master, interface_up, oi,
- OSPF6_INTERFACE_SSO_RETRY_INT,
- &oi->thread_sso);
+ event_add_timer(master, interface_up, oi,
+ OSPF6_INTERFACE_SSO_RETRY_INT, &oi->thread_sso);
return;
}
#endif /* __FreeBSD__ */
zlog_info(
"Scheduling %s for sso retry, trial count: %d",
oi->interface->name, oi->sso_try_cnt);
- thread_add_timer(master, interface_up, oi,
- OSPF6_INTERFACE_SSO_RETRY_INT,
- &oi->thread_sso);
+ event_add_timer(master, interface_up, oi,
+ OSPF6_INTERFACE_SSO_RETRY_INT,
+ &oi->thread_sso);
}
return;
}
/* Schedule Hello */
if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
&& !if_is_loopback(oi->interface)) {
- thread_add_timer(master, ospf6_hello_send, oi, 0,
- &oi->thread_send_hello);
+ event_add_timer(master, ospf6_hello_send, oi, 0,
+ &oi->thread_send_hello);
}
/* decide next interface state */
ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
else {
ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
- thread_add_timer(master, wait_timer, oi, oi->dead_interval,
- &oi->thread_wait_timer);
+ event_add_timer(master, wait_timer, oi, oi->dead_interval,
+ &oi->thread_wait_timer);
}
}
-void wait_timer(struct thread *thread)
+void wait_timer(struct event *thread)
{
struct ospf6_interface *oi;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi && oi->interface);
if (IS_OSPF6_DEBUG_INTERFACE)
ospf6_interface_state_change(dr_election(oi), oi);
}
-void backup_seen(struct thread *thread)
+void backup_seen(struct event *thread)
{
struct ospf6_interface *oi;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi && oi->interface);
if (IS_OSPF6_DEBUG_INTERFACE)
ospf6_interface_state_change(dr_election(oi), oi);
}
-void neighbor_change(struct thread *thread)
+void neighbor_change(struct event *thread)
{
struct ospf6_interface *oi;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi && oi->interface);
if (IS_OSPF6_DEBUG_INTERFACE)
ospf6_interface_state_change(dr_election(oi), oi);
}
-void interface_down(struct thread *thread)
+void interface_down(struct event *thread)
{
struct ospf6_interface *oi;
struct listnode *node, *nnode;
struct ospf6_neighbor *on;
struct ospf6 *ospf6;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi && oi->interface);
if (IS_OSPF6_DEBUG_INTERFACE)
oi->interface->name);
/* Stop Hellos */
- THREAD_OFF(oi->thread_send_hello);
+ EVENT_OFF(oi->thread_send_hello);
/* Stop trying to set socket options. */
- THREAD_OFF(oi->thread_sso);
+ EVENT_OFF(oi->thread_sso);
/* Cease the HELPER role for all the neighbours
* of this interface.
if (oi->on_write_q) {
listnode_delete(ospf6->oi_write_q, oi);
if (list_isempty(ospf6->oi_write_q))
- thread_cancel(&ospf6->t_write);
+ event_cancel(&ospf6->t_write);
oi->on_write_q = 0;
}
if (use_json) {
timerclear(&res);
- if (thread_is_scheduled(oi->thread_send_lsupdate))
+ if (event_is_scheduled(oi->thread_send_lsupdate))
timersub(&oi->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
duration);
json_object_string_add(
json_obj, "lsUpdateSendThread",
- (thread_is_scheduled(oi->thread_send_lsupdate)
- ? "on"
- : "off"));
+ (event_is_scheduled(oi->thread_send_lsupdate) ? "on"
+ : "off"));
json_arr = json_object_new_array();
for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
json_arr);
timerclear(&res);
- if (thread_is_scheduled(oi->thread_send_lsack))
+ if (event_is_scheduled(oi->thread_send_lsack))
timersub(&oi->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
duration);
json_object_string_add(
json_obj, "lsAckSendThread",
- (thread_is_scheduled(oi->thread_send_lsack) ? "on"
- : "off"));
+ (event_is_scheduled(oi->thread_send_lsack) ? "on"
+ : "off"));
json_arr = json_object_new_array();
for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
} else {
timerclear(&res);
- if (thread_is_scheduled(oi->thread_send_lsupdate))
+ if (event_is_scheduled(oi->thread_send_lsupdate))
timersub(&oi->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
oi->lsupdate_list->count, duration,
- (thread_is_scheduled(oi->thread_send_lsupdate)
- ? "on"
- : "off"));
+ (event_is_scheduled(oi->thread_send_lsupdate) ? "on"
+ : "off"));
for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (thread_is_scheduled(oi->thread_send_lsack))
+ if (event_is_scheduled(oi->thread_send_lsack))
timersub(&oi->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSAck in Time %s [thread %s]\n",
oi->lsack_list->count, duration,
- (thread_is_scheduled(oi->thread_send_lsack) ? "on"
- : "off"));
+ (event_is_scheduled(oi->thread_send_lsack) ? "on"
+ : "off"));
for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
}
/* re-establish adjacencies */
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
- THREAD_OFF(on->inactivity_timer);
- thread_add_event(master, inactivity_timer, on, 0, NULL);
+ EVENT_OFF(on->inactivity_timer);
+ event_add_event(master, inactivity_timer, on, 0, NULL);
}
return CMD_SUCCESS;
/* re-establish adjacencies */
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
- THREAD_OFF(on->inactivity_timer);
- thread_add_event(master, inactivity_timer, on, 0, NULL);
+ EVENT_OFF(on->inactivity_timer);
+ event_add_event(master, inactivity_timer, on, 0, NULL);
}
return CMD_SUCCESS;
/*
* If the thread is scheduled, send the new hello now.
*/
- if (thread_is_scheduled(oi->thread_send_hello)) {
- THREAD_OFF(oi->thread_send_hello);
+ if (event_is_scheduled(oi->thread_send_hello)) {
+ EVENT_OFF(oi->thread_send_hello);
- thread_add_timer(master, ospf6_hello_send, oi, 0,
- &oi->thread_send_hello);
+ event_add_timer(master, ospf6_hello_send, oi, 0,
+ &oi->thread_send_hello);
}
return CMD_SUCCESS;
}
assert(oi);
SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
- THREAD_OFF(oi->thread_send_hello);
- THREAD_OFF(oi->thread_sso);
+ EVENT_OFF(oi->thread_send_hello);
+ EVENT_OFF(oi->thread_sso);
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
- THREAD_OFF(on->inactivity_timer);
- thread_add_event(master, inactivity_timer, on, 0, NULL);
+ EVENT_OFF(on->inactivity_timer);
+ event_add_event(master, inactivity_timer, on, 0, NULL);
}
return CMD_SUCCESS;
assert(oi);
UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
- THREAD_OFF(oi->thread_send_hello);
- THREAD_OFF(oi->thread_sso);
+ EVENT_OFF(oi->thread_send_hello);
+ EVENT_OFF(oi->thread_sso);
/* don't send hellos over loopback interface */
if (!if_is_loopback(oi->interface))
- thread_add_timer(master, ospf6_hello_send, oi, 0,
- &oi->thread_send_hello);
+ event_add_timer(master, ospf6_hello_send, oi, 0,
+ &oi->thread_send_hello);
return CMD_SUCCESS;
}
}
/* Reset the interface */
- thread_execute(master, interface_down, oi, 0);
- thread_execute(master, interface_up, oi, 0);
+ event_execute(master, interface_down, oi, 0);
+ event_execute(master, interface_up, oi, 0);
return CMD_SUCCESS;
}
oi->type = type;
/* Reset the interface */
- thread_execute(master, interface_down, oi, 0);
- thread_execute(master, interface_up, oi, 0);
+ event_execute(master, interface_down, oi, 0);
+ event_execute(master, interface_up, oi, 0);
return CMD_SUCCESS;
}
zlog_debug("Interface %s: clear by reset", ifp->name);
/* Reset the interface */
- thread_execute(master, interface_down, oi, 0);
- thread_execute(master, interface_up, oi, 0);
+ event_execute(master, interface_down, oi, 0);
+ event_execute(master, interface_up, oi, 0);
}
/* Clear interface */
/* Interface socket setting trial counter, resets on success */
uint8_t sso_try_cnt;
- struct thread *thread_sso;
+ struct event *thread_sso;
/* OSPF6 Interface flag */
char flag;
struct ospf6_lsdb *lsack_list;
/* Ongoing Tasks */
- struct thread *thread_send_hello;
- struct thread *thread_send_lsupdate;
- struct thread *thread_send_lsack;
+ struct event *thread_send_hello;
+ struct event *thread_send_lsupdate;
+ struct event *thread_send_lsack;
- struct thread *thread_network_lsa;
- struct thread *thread_link_lsa;
- struct thread *thread_intra_prefix_lsa;
- struct thread *thread_as_extern_lsa;
- struct thread *thread_wait_timer;
+ struct event *thread_network_lsa;
+ struct event *thread_link_lsa;
+ struct event *thread_intra_prefix_lsa;
+ struct event *thread_as_extern_lsa;
+ struct event *thread_wait_timer;
struct ospf6_route_table *route_connected;
ospf6_interface_get_global_address(struct interface *ifp);
/* interface event */
-extern void interface_up(struct thread *thread);
-extern void interface_down(struct thread *thread);
-extern void wait_timer(struct thread *thread);
-extern void backup_seen(struct thread *thread);
-extern void neighbor_change(struct thread *thread);
+extern void interface_up(struct event *thread);
+extern void interface_down(struct event *thread);
+extern void wait_timer(struct event *thread);
+extern void backup_seen(struct event *thread);
+extern void neighbor_change(struct event *thread);
extern void ospf6_interface_init(void);
extern void ospf6_interface_clear(struct interface *ifp);
#include "log.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "if.h"
#include "prefix.h"
return OSPF6_NOT_STUB_ROUTER;
}
-void ospf6_router_lsa_originate(struct thread *thread)
+void ospf6_router_lsa_originate(struct event *thread)
{
struct ospf6_area *oa;
uint32_t router;
int count;
- oa = (struct ospf6_area *)THREAD_ARG(thread);
+ oa = (struct ospf6_area *)EVENT_ARG(thread);
if (oa->ospf6->gr_info.restart_in_progress) {
if (IS_DEBUG_OSPF6_GR)
return 0;
}
-void ospf6_network_lsa_originate(struct thread *thread)
+void ospf6_network_lsa_originate(struct event *thread)
{
struct ospf6_interface *oi;
struct listnode *i;
uint16_t type;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
/* The interface must be enabled until here. A Network-LSA of a
disabled interface (but was once enabled) should be flushed
return 0;
}
-void ospf6_link_lsa_originate(struct thread *thread)
+void ospf6_link_lsa_originate(struct event *thread)
{
struct ospf6_interface *oi;
struct ospf6_route *route;
struct ospf6_prefix *op;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi->area);
return 0;
}
-void ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
+void ospf6_intra_prefix_lsa_originate_stub(struct event *thread)
{
struct ospf6_area *oa;
struct ospf6_route_table *route_advertise;
int ls_id = 0;
- oa = (struct ospf6_area *)THREAD_ARG(thread);
+ oa = (struct ospf6_area *)EVENT_ARG(thread);
if (oa->ospf6->gr_info.restart_in_progress) {
if (IS_DEBUG_OSPF6_GR)
}
-void ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)
+void ospf6_intra_prefix_lsa_originate_transit(struct event *thread)
{
struct ospf6_interface *oi;
char *start, *end, *current;
uint16_t type;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
assert(oi->area);
#define OSPF6_ROUTER_LSA_SCHEDULE(oa) \
do { \
if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
- thread_add_event(master, ospf6_router_lsa_originate, \
- oa, 0, &(oa)->thread_router_lsa); \
+ event_add_event(master, ospf6_router_lsa_originate, \
+ oa, 0, &(oa)->thread_router_lsa); \
} while (0)
#define OSPF6_NETWORK_LSA_SCHEDULE(oi) \
do { \
if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- thread_add_event(master, ospf6_network_lsa_originate, \
- oi, 0, &(oi)->thread_network_lsa); \
+ event_add_event(master, ospf6_network_lsa_originate, \
+ oi, 0, &(oi)->thread_network_lsa); \
} while (0)
#define OSPF6_LINK_LSA_SCHEDULE(oi) \
do { \
if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- thread_add_event(master, ospf6_link_lsa_originate, oi, \
- 0, &(oi)->thread_link_lsa); \
+ event_add_event(master, ospf6_link_lsa_originate, oi, \
+ 0, &(oi)->thread_link_lsa); \
} while (0)
#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oa) \
do { \
if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
- thread_add_event( \
+ event_add_event( \
master, ospf6_intra_prefix_lsa_originate_stub, \
oa, 0, &(oa)->thread_intra_prefix_lsa); \
} while (0)
#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi) \
do { \
if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- thread_add_event( \
+ event_add_event( \
master, \
ospf6_intra_prefix_lsa_originate_transit, oi, \
0, &(oi)->thread_intra_prefix_lsa); \
#define OSPF6_AS_EXTERN_LSA_SCHEDULE(oi) \
do { \
if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- thread_add_event(master, ospf6_orig_as_external_lsa, \
- oi, 0, &(oi)->thread_as_extern_lsa); \
+ event_add_event(master, ospf6_orig_as_external_lsa, \
+ oi, 0, &(oi)->thread_as_extern_lsa); \
} while (0)
#define OSPF6_ROUTER_LSA_EXECUTE(oa) \
do { \
if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \
- thread_execute(master, ospf6_router_lsa_originate, oa, \
- 0); \
+ event_execute(master, ospf6_router_lsa_originate, oa, \
+ 0); \
} while (0)
#define OSPF6_NETWORK_LSA_EXECUTE(oi) \
do { \
- THREAD_OFF((oi)->thread_network_lsa); \
- thread_execute(master, ospf6_network_lsa_originate, oi, 0); \
+ EVENT_OFF((oi)->thread_network_lsa); \
+ event_execute(master, ospf6_network_lsa_originate, oi, 0); \
} while (0)
#define OSPF6_LINK_LSA_EXECUTE(oi) \
do { \
if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \
- thread_execute(master, ospf6_link_lsa_originate, oi, \
- 0); \
+ event_execute(master, ospf6_link_lsa_originate, oi, \
+ 0); \
} while (0)
#define OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi) \
do { \
- THREAD_OFF((oi)->thread_intra_prefix_lsa); \
- thread_execute(master, \
- ospf6_intra_prefix_lsa_originate_transit, oi, \
- 0); \
+ EVENT_OFF((oi)->thread_intra_prefix_lsa); \
+ event_execute(master, \
+ ospf6_intra_prefix_lsa_originate_transit, oi, \
+ 0); \
} while (0)
#define OSPF6_AS_EXTERN_LSA_EXECUTE(oi) \
do { \
- THREAD_OFF((oi)->thread_as_extern_lsa); \
- thread_execute(master, ospf6_orig_as_external_lsa, oi, 0); \
+ EVENT_OFF((oi)->thread_as_extern_lsa); \
+ event_execute(master, ospf6_orig_as_external_lsa, oi, 0); \
} while (0)
/* Function Prototypes */
struct ospf6_lsa *lsa);
extern int ospf6_router_is_stub_router(struct ospf6_lsa *lsa);
-extern void ospf6_router_lsa_originate(struct thread *thread);
-extern void ospf6_network_lsa_originate(struct thread *thread);
-extern void ospf6_link_lsa_originate(struct thread *thread);
-extern void ospf6_intra_prefix_lsa_originate_transit(struct thread *thread);
-extern void ospf6_intra_prefix_lsa_originate_stub(struct thread *thread);
+extern void ospf6_router_lsa_originate(struct event *thread);
+extern void ospf6_network_lsa_originate(struct event *thread);
+extern void ospf6_link_lsa_originate(struct event *thread);
+extern void ospf6_intra_prefix_lsa_originate_transit(struct event *thread);
+extern void ospf6_intra_prefix_lsa_originate_stub(struct event *thread);
extern void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa);
extern void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa);
-extern void ospf6_orig_as_external_lsa(struct thread *thread);
+extern void ospf6_orig_as_external_lsa(struct event *thread);
extern void ospf6_intra_route_calculation(struct ospf6_area *oa);
extern void ospf6_intra_brouter_calculation(struct ospf6_area *oa);
extern void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
#include "vty.h"
#include "command.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "checksum.h"
#include "frrstr.h"
if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type))
zlog_debug("LSA: Premature aging: %s", lsa->name);
- THREAD_OFF(lsa->expire);
- THREAD_OFF(lsa->refresh);
+ EVENT_OFF(lsa->expire);
+ EVENT_OFF(lsa->refresh);
/*
* We clear the LSA from the neighbor retx lists now because it
ospf6_flood_clear(lsa);
lsa->header->age = htons(OSPF_LSA_MAXAGE);
- thread_execute(master, ospf6_lsa_expire, lsa, 0);
+ event_execute(master, ospf6_lsa_expire, lsa, 0);
}
/* check which is more recent. if a is more recent, return -1;
assert(lsa->lock == 0);
/* cancel threads */
- THREAD_OFF(lsa->expire);
- THREAD_OFF(lsa->refresh);
+ EVENT_OFF(lsa->expire);
+ EVENT_OFF(lsa->refresh);
/* do free */
XFREE(MTYPE_OSPF6_LSA_HEADER, lsa->header);
/* ospf6 lsa expiry */
-void ospf6_lsa_expire(struct thread *thread)
+void ospf6_lsa_expire(struct event *thread)
{
struct ospf6_lsa *lsa;
struct ospf6 *ospf6;
- lsa = (struct ospf6_lsa *)THREAD_ARG(thread);
+ lsa = (struct ospf6_lsa *)EVENT_ARG(thread);
assert(lsa && lsa->header);
assert(OSPF6_LSA_IS_MAXAGE(lsa));
assert(!lsa->refresh);
- lsa->expire = (struct thread *)NULL;
+ lsa->expire = (struct event *)NULL;
if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) {
zlog_debug("LSA Expire:");
ospf6_maxage_remove(ospf6);
}
-void ospf6_lsa_refresh(struct thread *thread)
+void ospf6_lsa_refresh(struct event *thread)
{
struct ospf6_lsa *old, *self, *new;
struct ospf6_lsdb *lsdb_self;
- old = (struct ospf6_lsa *)THREAD_ARG(thread);
+ old = (struct ospf6_lsa *)EVENT_ARG(thread);
assert(old && old->header);
- old->refresh = (struct thread *)NULL;
+ old->refresh = (struct event *)NULL;
lsdb_self = ospf6_get_scoped_lsdb_self(old);
self = ospf6_lsdb_lookup(old->header->type, old->header->id,
new = ospf6_lsa_create(self->header);
new->lsdb = old->lsdb;
- thread_add_timer(master, ospf6_lsa_refresh, new, OSPF_LS_REFRESH_TIME,
- &new->refresh);
+ event_add_timer(master, ospf6_lsa_refresh, new, OSPF_LS_REFRESH_TIME,
+ &new->refresh);
/* store it in the LSDB for self-originated LSAs */
ospf6_lsdb_add(ospf6_lsa_copy(new), lsdb_self);
struct timeval received; /* used by MinLSArrival check */
struct timeval installed;
- struct thread *expire;
- struct thread *refresh; /* For self-originated LSA */
+ struct event *expire;
+ struct event *refresh; /* For self-originated LSA */
int retrans_count;
extern struct ospf6_lsa *ospf6_lsa_lock(struct ospf6_lsa *lsa);
extern struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *lsa);
-extern void ospf6_lsa_expire(struct thread *thread);
-extern void ospf6_lsa_refresh(struct thread *thread);
+extern void ospf6_lsa_expire(struct event *thread);
+extern void ospf6_lsa_refresh(struct event *thread);
extern unsigned short ospf6_lsa_checksum(struct ospf6_lsa_header *lsah);
extern int ospf6_lsa_checksum_valid(struct ospf6_lsa_header *lsah);
htonl(OSPF_MAX_SEQUENCE_NUMBER + 1);
ospf6_lsa_checksum(lsa->header);
- THREAD_OFF(lsa->refresh);
- thread_execute(master, ospf6_lsa_refresh, lsa, 0);
+ EVENT_OFF(lsa->refresh);
+ event_execute(master, ospf6_lsa_refresh, lsa, 0);
} else {
zlog_debug("calling ospf6_lsdb_remove %s", lsa->name);
ospf6_lsdb_remove(lsa, lsdb);
#include <stdlib.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "command.h"
#include "vty.h"
struct option longopts[] = {{0}};
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
static void __attribute__((noreturn)) ospf6_exit(int status)
{
#include "log.h"
#include "vty.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "lib_errors.h"
#include "checksum.h"
oi->hello_in++;
/* Execute neighbor events */
- thread_execute(master, hello_received, on, 0);
+ event_execute(master, hello_received, on, 0);
if (twoway)
- thread_execute(master, twoway_received, on, 0);
+ event_execute(master, twoway_received, on, 0);
else {
if (OSPF6_GR_IS_ACTIVE_HELPER(on)) {
if (IS_DEBUG_OSPF6_GR)
* receives one_way hellow when it acts as HELPER for
* that specific neighbor.
*/
- thread_execute(master, oneway_received, on, 0);
+ event_execute(master, oneway_received, on, 0);
}
}
/* Schedule interface events */
if (backupseen)
- thread_add_event(master, backup_seen, oi, 0, NULL);
+ event_add_event(master, backup_seen, oi, 0, NULL);
if (neighborchange)
- thread_add_event(master, neighbor_change, oi, 0, NULL);
+ event_add_event(master, neighbor_change, oi, 0, NULL);
if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL)
OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
return;
case OSPF6_NEIGHBOR_INIT:
- thread_execute(master, twoway_received, on, 0);
+ event_execute(master, twoway_received, on, 0);
if (on->state != OSPF6_NEIGHBOR_EXSTART) {
if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
&& !CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)
&& ntohl(dbdesc->seqnum) == on->dbdesc_seqnum) {
/* execute NegotiationDone */
- thread_execute(master, negotiation_done, on, 0);
+ event_execute(master, negotiation_done, on, 0);
/* Record neighbor options */
memcpy(on->options, dbdesc->options,
zlog_warn(
"DbDesc recv: Master/Slave bit mismatch Nbr %s",
on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) {
zlog_warn("DbDesc recv: Initialize bit mismatch Nbr %s",
on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
if (memcmp(on->options, dbdesc->options, sizeof(on->options))) {
zlog_warn("DbDesc recv: Option field mismatch Nbr %s",
on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
"DbDesc recv: Sequence number mismatch Nbr %s (received %#lx, %#lx expected)",
on->name, (unsigned long)ntohl(dbdesc->seqnum),
(unsigned long)on->dbdesc_seqnum);
- thread_add_event(master, seqnumber_mismatch, on, 0,
+ event_add_event(master, seqnumber_mismatch, on, 0,
NULL);
return;
}
zlog_warn(
"DbDesc recv: Not duplicate dbdesc in state %s Nbr %s",
ospf6_neighbor_state_str[on->state], on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0, NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0, NULL);
return;
default:
zlog_debug(
"SeqNumMismatch (E-bit mismatch), discard");
ospf6_lsa_delete(his);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
/* schedule send lsreq */
if (on->request_list->count)
- thread_add_event(master, ospf6_lsreq_send, on, 0,
- &on->thread_send_lsreq);
+ event_add_event(master, ospf6_lsreq_send, on, 0,
+ &on->thread_send_lsreq);
- THREAD_OFF(on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
/* More bit check */
if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT)
&& !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT))
- thread_add_event(master, exchange_done, on, 0,
- &on->thread_exchange_done);
+ event_add_event(master, exchange_done, on, 0,
+ &on->thread_exchange_done);
else {
- thread_add_event(master, ospf6_dbdesc_send_newone, on, 0,
- &on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send_newone, on, 0,
+ &on->thread_send_dbdesc);
}
/* save last received dbdesc */
return;
case OSPF6_NEIGHBOR_INIT:
- thread_execute(master, twoway_received, on, 0);
+ event_execute(master, twoway_received, on, 0);
if (on->state != OSPF6_NEIGHBOR_EXSTART) {
if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
on->dbdesc_seqnum = ntohl(dbdesc->seqnum);
/* schedule NegotiationDone */
- thread_execute(master, negotiation_done, on, 0);
+ event_execute(master, negotiation_done, on, 0);
/* Record neighbor options */
memcpy(on->options, dbdesc->options,
if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Duplicated dbdesc causes retransmit");
- THREAD_OFF(on->thread_send_dbdesc);
- thread_add_event(master, ospf6_dbdesc_send, on, 0,
- &on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
return;
}
zlog_warn(
"DbDesc slave recv: Master/Slave bit mismatch Nbr %s",
on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
zlog_warn(
"DbDesc slave recv: Initialize bit mismatch Nbr %s",
on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
zlog_warn(
"DbDesc slave recv: Option field mismatch Nbr %s",
on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
"DbDesc slave recv: Sequence number mismatch Nbr %s (received %#lx, %#lx expected)",
on->name, (unsigned long)ntohl(dbdesc->seqnum),
(unsigned long)on->dbdesc_seqnum + 1);
- thread_add_event(master, seqnumber_mismatch, on, 0,
+ event_add_event(master, seqnumber_mismatch, on, 0,
NULL);
return;
}
if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Duplicated dbdesc causes retransmit");
- THREAD_OFF(on->thread_send_dbdesc);
- thread_add_event(master, ospf6_dbdesc_send, on, 0,
- &on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
return;
}
zlog_warn(
"DbDesc slave recv: Not duplicate dbdesc in state %s Nbr %s",
ospf6_neighbor_state_str[on->state], on->name);
- thread_add_event(master, seqnumber_mismatch, on, 0, NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0, NULL);
return;
default:
if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
zlog_debug("E-bit mismatch with LSA Headers");
ospf6_lsa_delete(his);
- thread_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ event_add_event(master, seqnumber_mismatch, on, 0,
+ NULL);
return;
}
/* schedule send lsreq */
if (on->request_list->count)
- thread_add_event(master, ospf6_lsreq_send, on, 0,
- &on->thread_send_lsreq);
+ event_add_event(master, ospf6_lsreq_send, on, 0,
+ &on->thread_send_lsreq);
- THREAD_OFF(on->thread_send_dbdesc);
- thread_add_event(master, ospf6_dbdesc_send_newone, on, 0,
- &on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send_newone, on, 0,
+ &on->thread_send_dbdesc);
/* save last received dbdesc */
memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc));
"Can't find requested lsa [%s Id:%pI4 Adv:%pI4] send badLSReq",
ospf6_lstype_name(e->type), &e->id,
&e->adv_router);
- thread_add_event(master, bad_lsreq, on, 0, NULL);
+ event_add_event(master, bad_lsreq, on, 0, NULL);
return;
}
assert(p == OSPF6_MESSAGE_END(oh));
/* schedule send lsupdate */
- THREAD_OFF(on->thread_send_lsupdate);
- thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
- &on->thread_send_lsupdate);
+ EVENT_OFF(on->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
+ &on->thread_send_lsupdate);
}
/* Verify, that the specified memory area contains exactly N valid IPv6
return OSPF6_READ_CONTINUE;
}
-void ospf6_receive(struct thread *thread)
+void ospf6_receive(struct event *thread)
{
int sockfd;
struct ospf6 *ospf6;
int count = 0;
/* add next read thread */
- ospf6 = THREAD_ARG(thread);
- sockfd = THREAD_FD(thread);
+ ospf6 = EVENT_ARG(thread);
+ sockfd = EVENT_FD(thread);
- thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
- &ospf6->t_ospf6_receive);
+ event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
+ &ospf6->t_ospf6_receive);
while (count < ospf6->write_oi_count) {
count++;
return length;
}
-static void ospf6_write(struct thread *thread)
+static void ospf6_write(struct event *thread)
{
- struct ospf6 *ospf6 = THREAD_ARG(thread);
+ struct ospf6 *ospf6 = EVENT_ARG(thread);
struct ospf6_interface *oi;
struct ospf6_header *oh;
struct ospf6_packet *op;
/* If packets still remain in queue, call write thread. */
if (!list_isempty(ospf6->oi_write_q))
- thread_add_write(master, ospf6_write, ospf6, ospf6->fd,
- &ospf6->t_write);
+ event_add_write(master, ospf6_write, ospf6, ospf6->fd,
+ &ospf6->t_write);
}
-void ospf6_hello_send(struct thread *thread)
+void ospf6_hello_send(struct event *thread)
{
struct ospf6_interface *oi;
struct ospf6_packet *op;
uint16_t length = OSPF6_HEADER_SIZE;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
if (oi->state <= OSPF6_INTERFACE_DOWN) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND_HDR))
ospf6_packet_add_top(oi, op);
/* set next thread */
- thread_add_timer(master, ospf6_hello_send, oi, oi->hello_interval,
- &oi->thread_send_hello);
+ event_add_timer(master, ospf6_hello_send, oi, oi->hello_interval,
+ &oi->thread_send_hello);
OSPF6_MESSAGE_WRITE_ON(oi);
}
return length;
}
-void ospf6_dbdesc_send(struct thread *thread)
+void ospf6_dbdesc_send(struct event *thread)
{
struct ospf6_neighbor *on;
uint16_t length = OSPF6_HEADER_SIZE;
struct ospf6_packet *op;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
if (on->state < OSPF6_NEIGHBOR_EXSTART) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND))
/* set next thread if master */
if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
- thread_add_timer(master, ospf6_dbdesc_send, on,
- on->ospf6_if->rxmt_interval,
- &on->thread_send_dbdesc);
+ event_add_timer(master, ospf6_dbdesc_send, on,
+ on->ospf6_if->rxmt_interval,
+ &on->thread_send_dbdesc);
op = ospf6_packet_new(on->ospf6_if->ifmtu);
ospf6_make_header(OSPF6_MESSAGE_TYPE_DBDESC, on->ospf6_if, op->s);
OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
}
-void ospf6_dbdesc_send_newone(struct thread *thread)
+void ospf6_dbdesc_send_newone(struct event *thread)
{
struct ospf6_neighbor *on;
struct ospf6_lsa *lsa, *lsanext;
unsigned int size = 0;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
ospf6_lsdb_remove_all(on->dbdesc_list);
/* move LSAs from summary_list to dbdesc_list (within neighbor
if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
!CHECK_FLAG(on->dbdesc_last.bits, OSPF6_DBDESC_MBIT)
&& !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT))
- thread_add_event(master, exchange_done, on, 0,
- &on->thread_exchange_done);
+ event_add_event(master, exchange_done, on, 0,
+ &on->thread_exchange_done);
- thread_execute(master, ospf6_dbdesc_send, on, 0);
+ event_execute(master, ospf6_dbdesc_send, on, 0);
}
static uint16_t ospf6_make_lsreq(struct ospf6_neighbor *on, struct stream *s)
return length;
}
-void ospf6_lsreq_send(struct thread *thread)
+void ospf6_lsreq_send(struct event *thread)
{
struct ospf6_neighbor *on;
struct ospf6_packet *op;
uint16_t length = OSPF6_HEADER_SIZE;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
/* LSReq will be sent only in ExStart or Loading */
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
/* schedule loading_done if request list is empty */
if (on->request_list->count == 0) {
- thread_add_event(master, loading_done, on, 0, NULL);
+ event_add_event(master, loading_done, on, 0, NULL);
return;
}
/* set next thread */
if (on->request_list->count != 0) {
- thread_add_timer(master, ospf6_lsreq_send, on,
- on->ospf6_if->rxmt_interval,
- &on->thread_send_lsreq);
+ event_add_timer(master, ospf6_lsreq_send, on,
+ on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsreq);
}
}
listnode_add(oi->area->ospf6->oi_write_q, oi);
oi->on_write_q = 1;
}
- thread_execute(master, ospf6_write, oi->area->ospf6, 0);
+ event_execute(master, ospf6_write, oi->area->ospf6, 0);
} else
OSPF6_MESSAGE_WRITE_ON(oi);
}
return length;
}
-void ospf6_lsupdate_send_neighbor(struct thread *thread)
+void ospf6_lsupdate_send_neighbor(struct event *thread)
{
struct ospf6_neighbor *on;
struct ospf6_packet *op;
uint16_t length = OSPF6_HEADER_SIZE;
int lsa_cnt = 0;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND_HDR))
zlog_debug("LSUpdate to neighbor %s", on->name);
ospf6_packet_free(op);
if (on->lsupdate_list->count != 0) {
- thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
- &on->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
+ &on->thread_send_lsupdate);
} else if (on->retrans_list->count != 0) {
- thread_add_timer(master, ospf6_lsupdate_send_neighbor, on,
- on->ospf6_if->rxmt_interval,
- &on->thread_send_lsupdate);
+ event_add_timer(master, ospf6_lsupdate_send_neighbor, on,
+ on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsupdate);
}
}
return length;
}
-void ospf6_lsupdate_send_interface(struct thread *thread)
+void ospf6_lsupdate_send_interface(struct event *thread)
{
struct ospf6_interface *oi;
struct ospf6_packet *op;
uint16_t length = OSPF6_HEADER_SIZE;
int lsa_cnt = 0;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
if (oi->state <= OSPF6_INTERFACE_WAITING) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE,
ospf6_packet_free(op);
if (oi->lsupdate_list->count > 0) {
- thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
- &oi->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
+ &oi->thread_send_lsupdate);
}
}
-void ospf6_lsack_send_neighbor(struct thread *thread)
+void ospf6_lsack_send_neighbor(struct event *thread)
{
struct ospf6_neighbor *on;
struct ospf6_packet *op;
uint16_t length = OSPF6_HEADER_SIZE;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
OSPF6_MESSAGE_WRITE_ON(on->ospf6_if);
if (on->lsack_list->count > 0)
- thread_add_event(master, ospf6_lsack_send_neighbor, on, 0,
- &on->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, on, 0,
+ &on->thread_send_lsack);
}
static uint16_t ospf6_make_lsack_interface(struct ospf6_interface *oi,
> ospf6_packet_max(oi)) {
/* if we run out of packet size/space here,
better to try again soon. */
- THREAD_OFF(oi->thread_send_lsack);
- thread_add_event(master, ospf6_lsack_send_interface, oi,
- 0, &oi->thread_send_lsack);
+ EVENT_OFF(oi->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_interface, oi,
+ 0, &oi->thread_send_lsack);
ospf6_lsa_unlock(lsa);
if (lsanext)
return length;
}
-void ospf6_lsack_send_interface(struct thread *thread)
+void ospf6_lsack_send_interface(struct event *thread)
{
struct ospf6_interface *oi;
struct ospf6_packet *op;
uint16_t length = OSPF6_HEADER_SIZE;
- oi = (struct ospf6_interface *)THREAD_ARG(thread);
+ oi = (struct ospf6_interface *)EVENT_ARG(thread);
if (oi->state <= OSPF6_INTERFACE_WAITING) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
OSPF6_MESSAGE_WRITE_ON(oi);
if (oi->lsack_list->count > 0)
- thread_add_event(master, ospf6_lsack_send_interface, oi, 0,
- &oi->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_interface, oi, 0,
+ &oi->thread_send_lsack);
}
/* Commands */
extern int ospf6_iobuf_size(unsigned int size);
extern void ospf6_message_terminate(void);
-extern void ospf6_receive(struct thread *thread);
-
-extern void ospf6_hello_send(struct thread *thread);
-extern void ospf6_dbdesc_send(struct thread *thread);
-extern void ospf6_dbdesc_send_newone(struct thread *thread);
-extern void ospf6_lsreq_send(struct thread *thread);
-extern void ospf6_lsupdate_send_interface(struct thread *thread);
-extern void ospf6_lsupdate_send_neighbor(struct thread *thread);
-extern void ospf6_lsack_send_interface(struct thread *thread);
-extern void ospf6_lsack_send_neighbor(struct thread *thread);
+extern void ospf6_receive(struct event *thread);
+
+extern void ospf6_hello_send(struct event *thread);
+extern void ospf6_dbdesc_send(struct event *thread);
+extern void ospf6_dbdesc_send_newone(struct event *thread);
+extern void ospf6_lsreq_send(struct event *thread);
+extern void ospf6_lsupdate_send_interface(struct event *thread);
+extern void ospf6_lsupdate_send_neighbor(struct event *thread);
+extern void ospf6_lsack_send_interface(struct event *thread);
+extern void ospf6_lsack_send_neighbor(struct event *thread);
extern int config_write_ospf6_debug_message(struct vty *);
extern void install_element_ospf6_debug_message(void);
#include "log.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "command.h"
ospf6_lsdb_delete(on->lsupdate_list);
ospf6_lsdb_delete(on->lsack_list);
- THREAD_OFF(on->inactivity_timer);
+ EVENT_OFF(on->inactivity_timer);
- THREAD_OFF(on->last_dbdesc_release_timer);
+ EVENT_OFF(on->last_dbdesc_release_timer);
- THREAD_OFF(on->thread_send_dbdesc);
- THREAD_OFF(on->thread_send_lsreq);
- THREAD_OFF(on->thread_send_lsupdate);
- THREAD_OFF(on->thread_send_lsack);
- THREAD_OFF(on->thread_exchange_done);
- THREAD_OFF(on->thread_adj_ok);
+ EVENT_OFF(on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_lsreq);
+ EVENT_OFF(on->thread_send_lsupdate);
+ EVENT_OFF(on->thread_send_lsack);
+ EVENT_OFF(on->thread_exchange_done);
+ EVENT_OFF(on->thread_adj_ok);
- THREAD_OFF(on->gr_helper_info.t_grace_timer);
+ EVENT_OFF(on->gr_helper_info.t_grace_timer);
bfd_sess_free(&on->bfd_session);
XFREE(MTYPE_OSPF6_NEIGHBOR, on);
return 0;
}
-void hello_received(struct thread *thread)
+void hello_received(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *HelloReceived*", on->name);
/* reset Inactivity Timer */
- THREAD_OFF(on->inactivity_timer);
- thread_add_timer(master, inactivity_timer, on,
- on->ospf6_if->dead_interval, &on->inactivity_timer);
+ EVENT_OFF(on->inactivity_timer);
+ event_add_timer(master, inactivity_timer, on,
+ on->ospf6_if->dead_interval, &on->inactivity_timer);
if (on->state <= OSPF6_NEIGHBOR_DOWN)
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
}
-void twoway_received(struct thread *thread)
+void twoway_received(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state > OSPF6_NEIGHBOR_INIT)
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *2Way-Received*", on->name);
- thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
+ event_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
if (!need_adjacency(on)) {
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
- THREAD_OFF(on->thread_send_dbdesc);
- thread_add_event(master, ospf6_dbdesc_send, on, 0,
- &on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
}
-void negotiation_done(struct thread *thread)
+void negotiation_done(struct event *thread)
{
struct ospf6_neighbor *on;
struct ospf6_lsa *lsa, *lsanext;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state != OSPF6_NEIGHBOR_EXSTART)
OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
}
-static void ospf6_neighbor_last_dbdesc_release(struct thread *thread)
+static void ospf6_neighbor_last_dbdesc_release(struct event *thread)
{
- struct ospf6_neighbor *on = THREAD_ARG(thread);
+ struct ospf6_neighbor *on = EVENT_ARG(thread);
assert(on);
memset(&on->dbdesc_last, 0, sizeof(struct ospf6_dbdesc));
}
-void exchange_done(struct thread *thread)
+void exchange_done(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name);
- THREAD_OFF(on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
ospf6_lsdb_remove_all(on->dbdesc_list);
/* RFC 2328 (10.8): Release the last dbdesc after dead_interval */
if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) {
- THREAD_OFF(on->last_dbdesc_release_timer);
- thread_add_timer(master, ospf6_neighbor_last_dbdesc_release, on,
- on->ospf6_if->dead_interval,
- &on->last_dbdesc_release_timer);
+ EVENT_OFF(on->last_dbdesc_release_timer);
+ event_add_timer(master, ospf6_neighbor_last_dbdesc_release, on,
+ on->ospf6_if->dead_interval,
+ &on->last_dbdesc_release_timer);
}
if (on->request_list->count == 0)
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on,
OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
- thread_add_event(master, ospf6_lsreq_send, on, 0,
- &on->thread_send_lsreq);
+ event_add_event(master, ospf6_lsreq_send, on, 0,
+ &on->thread_send_lsreq);
}
}
if ((on->state == OSPF6_NEIGHBOR_LOADING)
|| (on->state == OSPF6_NEIGHBOR_EXCHANGE)) {
if (on->request_list->count == 0)
- thread_add_event(master, loading_done, on, 0, NULL);
+ event_add_event(master, loading_done, on, 0, NULL);
else if (on->last_ls_req == NULL) {
- THREAD_OFF(on->thread_send_lsreq);
- thread_add_event(master, ospf6_lsreq_send, on, 0,
- &on->thread_send_lsreq);
+ EVENT_OFF(on->thread_send_lsreq);
+ event_add_event(master, ospf6_lsreq_send, on, 0,
+ &on->thread_send_lsreq);
}
}
}
-void loading_done(struct thread *thread)
+void loading_done(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state != OSPF6_NEIGHBOR_LOADING)
OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
}
-void adj_ok(struct thread *thread)
+void adj_ok(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
- THREAD_OFF(on->thread_send_dbdesc);
- thread_add_event(master, ospf6_dbdesc_send, on, 0,
- &on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
} else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) {
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
}
}
-void seqnumber_mismatch(struct thread *thread)
+void seqnumber_mismatch(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
ospf6_neighbor_clear_ls_lists(on);
- THREAD_OFF(on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
- thread_add_event(master, ospf6_dbdesc_send, on, 0,
- &on->thread_send_dbdesc);
+ event_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
}
-void bad_lsreq(struct thread *thread)
+void bad_lsreq(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
ospf6_neighbor_clear_ls_lists(on);
- THREAD_OFF(on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_dbdesc);
on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
- thread_add_event(master, ospf6_dbdesc_send, on, 0,
- &on->thread_send_dbdesc);
-
+ event_add_event(master, ospf6_dbdesc_send, on, 0,
+ &on->thread_send_dbdesc);
}
-void oneway_received(struct thread *thread)
+void oneway_received(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
- thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
+ event_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
ospf6_neighbor_clear_ls_lists(on);
- THREAD_OFF(on->thread_send_dbdesc);
- THREAD_OFF(on->thread_send_lsreq);
- THREAD_OFF(on->thread_send_lsupdate);
- THREAD_OFF(on->thread_send_lsack);
- THREAD_OFF(on->thread_exchange_done);
- THREAD_OFF(on->thread_adj_ok);
+ EVENT_OFF(on->thread_send_dbdesc);
+ EVENT_OFF(on->thread_send_lsreq);
+ EVENT_OFF(on->thread_send_lsupdate);
+ EVENT_OFF(on->thread_send_lsack);
+ EVENT_OFF(on->thread_exchange_done);
+ EVENT_OFF(on->thread_adj_ok);
}
-void inactivity_timer(struct thread *thread)
+void inactivity_timer(struct event *thread)
{
struct ospf6_neighbor *on;
- on = (struct ospf6_neighbor *)THREAD_ARG(thread);
+ on = (struct ospf6_neighbor *)EVENT_ARG(thread);
assert(on);
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
ospf6_neighbor_state_change(
OSPF6_NEIGHBOR_DOWN, on,
OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
- thread_add_event(master, neighbor_change, on->ospf6_if, 0,
- NULL);
+ event_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
listnode_delete(on->ospf6_if->neighbor_list, on);
ospf6_neighbor_delete(on);
"%s, Acting as HELPER for this neighbour, So restart the dead timer.",
__PRETTY_FUNCTION__);
- thread_add_timer(master, inactivity_timer, on,
- on->ospf6_if->dead_interval,
- &on->inactivity_timer);
+ event_add_timer(master, inactivity_timer, on,
+ on->ospf6_if->dead_interval,
+ &on->inactivity_timer);
}
}
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_dbdesc))
+ if (event_is_scheduled(on->thread_send_dbdesc))
timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaDbDescCount",
duration);
json_object_string_add(
json_neighbor, "dbDescSendThread",
- (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_dbdesc) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
json_object_array_add(
json_array);
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_lsreq))
+ if (event_is_scheduled(on->thread_send_lsreq))
timersub(&on->thread_send_lsreq->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaLsReqCount",
duration);
json_object_string_add(
json_neighbor, "lsReqSendThread",
- (thread_is_scheduled(on->thread_send_lsreq) ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_lsreq) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->request_list, lsa, lsanext))
json_object_array_add(
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_lsupdate))
+ if (event_is_scheduled(on->thread_send_lsupdate))
timersub(&on->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
duration);
json_object_string_add(
json_neighbor, "lsUpdateSendThread",
- (thread_is_scheduled(on->thread_send_lsupdate)
- ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_lsupdate) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
json_object_array_add(
json_array);
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_lsack))
+ if (event_is_scheduled(on->thread_send_lsack))
timersub(&on->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaLsAckCount",
duration);
json_object_string_add(
json_neighbor, "lsAckSendThread",
- (thread_is_scheduled(on->thread_send_lsack) ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_lsack) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->lsack_list, lsa, lsanext))
json_object_array_add(
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_dbdesc))
+ if (event_is_scheduled(on->thread_send_dbdesc))
timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
on->dbdesc_list->count, duration,
- (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_dbdesc) ? "on"
+ : "off"));
for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_lsreq))
+ if (event_is_scheduled(on->thread_send_lsreq))
timersub(&on->thread_send_lsreq->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSReq in Time %s [thread %s]\n",
on->request_list->count, duration,
- (thread_is_scheduled(on->thread_send_lsreq) ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_lsreq) ? "on"
+ : "off"));
for (ALL_LSDB(on->request_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_lsupdate))
+ if (event_is_scheduled(on->thread_send_lsupdate))
timersub(&on->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
on->lsupdate_list->count, duration,
- (thread_is_scheduled(on->thread_send_lsupdate)
- ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_lsupdate) ? "on"
+ : "off"));
for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (thread_is_scheduled(on->thread_send_lsack))
+ if (event_is_scheduled(on->thread_send_lsack))
timersub(&on->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSAck in Time %s [thread %s]\n",
on->lsack_list->count, duration,
- (thread_is_scheduled(on->thread_send_lsack) ? "on"
- : "off"));
+ (event_is_scheduled(on->thread_send_lsack) ? "on"
+ : "off"));
for (ALL_LSDB(on->lsack_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
* helper until this timer until
* this timer expires.
*/
- struct thread *t_grace_timer;
+ struct event *t_grace_timer;
/* Helper status */
uint32_t gr_helper_status;
struct ospf6_lsa *last_ls_req;
/* Inactivity timer */
- struct thread *inactivity_timer;
+ struct event *inactivity_timer;
/* Timer to release the last dbdesc packet */
- struct thread *last_dbdesc_release_timer;
+ struct event *last_dbdesc_release_timer;
/* Thread for sending message */
- struct thread *thread_send_dbdesc;
- struct thread *thread_send_lsreq;
- struct thread *thread_send_lsupdate;
- struct thread *thread_send_lsack;
- struct thread *thread_exchange_done;
- struct thread *thread_adj_ok;
+ struct event *thread_send_dbdesc;
+ struct event *thread_send_lsreq;
+ struct event *thread_send_lsupdate;
+ struct event *thread_send_lsack;
+ struct event *thread_exchange_done;
+ struct event *thread_adj_ok;
/* BFD information */
struct bfd_session_params *bfd_session;
void ospf6_neighbor_delete(struct ospf6_neighbor *on);
/* Neighbor event */
-extern void hello_received(struct thread *thread);
-extern void twoway_received(struct thread *thread);
-extern void negotiation_done(struct thread *thread);
-extern void exchange_done(struct thread *thread);
-extern void loading_done(struct thread *thread);
-extern void adj_ok(struct thread *thread);
-extern void seqnumber_mismatch(struct thread *thread);
-extern void bad_lsreq(struct thread *thread);
-extern void oneway_received(struct thread *thread);
-extern void inactivity_timer(struct thread *thread);
+extern void hello_received(struct event *thread);
+extern void twoway_received(struct event *thread);
+extern void negotiation_done(struct event *thread);
+extern void exchange_done(struct event *thread);
+extern void loading_done(struct event *thread);
+extern void adj_ok(struct event *thread);
+extern void seqnumber_mismatch(struct event *thread);
+extern void bad_lsreq(struct event *thread);
+extern void oneway_received(struct event *thread);
+extern void inactivity_timer(struct event *thread);
extern void ospf6_check_nbr_loading(struct ospf6_neighbor *on);
extern void ospf6_neighbor_init(void);
listnode_add(oi->area->ospf6->oi_write_q, (oi)); \
(oi)->on_write_q = 1; \
} \
- if (list_was_empty \
- && !list_isempty(oi->area->ospf6->oi_write_q)) \
- thread_add_write(master, ospf6_write, oi->area->ospf6, \
- oi->area->ospf6->fd, \
- &oi->area->ospf6->t_write); \
+ if (list_was_empty && \
+ !list_isempty(oi->area->ospf6->oi_write_q)) \
+ event_add_write(master, ospf6_write, oi->area->ospf6, \
+ oi->area->ospf6->fd, \
+ &oi->area->ospf6->t_write); \
} while (0)
#endif /* OSPF6_NETWORK_H */
#include "vty.h"
#include "linklist.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "plist.h"
#include "filter.h"
}
/* This function performs ABR related processing */
-static void ospf6_abr_task_timer(struct thread *thread)
+static void ospf6_abr_task_timer(struct event *thread)
{
- struct ospf6 *ospf6 = THREAD_ARG(thread);
+ struct ospf6 *ospf6 = EVENT_ARG(thread);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Running ABR task on timer");
void ospf6_schedule_abr_task(struct ospf6 *ospf6)
{
- if (thread_is_scheduled(ospf6->t_abr_task)) {
+ if (event_is_scheduled(ospf6->t_abr_task)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("ABR task already scheduled");
return;
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Scheduling ABR task");
- thread_add_timer(master, ospf6_abr_task_timer, ospf6,
- OSPF6_ABR_TASK_DELAY, &ospf6->t_abr_task);
+ event_add_timer(master, ospf6_abr_task_timer, ospf6,
+ OSPF6_ABR_TASK_DELAY, &ospf6->t_abr_task);
}
/* Flush the NSSA LSAs from the area */
route->path.origin.id, o->router_id,
o->lsdb);
if (old) {
- THREAD_OFF(old->refresh);
- thread_add_event(master, ospf6_lsa_refresh, old, 0,
- &old->refresh);
+ EVENT_OFF(old->refresh);
+ event_add_event(master, ospf6_lsa_refresh, old, 0,
+ &old->refresh);
} else {
ospf6_as_external_lsa_originate(route, o);
}
lsa)) {
if (IS_OSPF6_DEBUG_NSSA)
ospf6_lsa_header_print(lsa);
- THREAD_OFF(lsa->refresh);
- thread_add_event(master, ospf6_lsa_refresh, lsa,
- 0, &lsa->refresh);
+ EVENT_OFF(lsa->refresh);
+ event_add_event(master, ospf6_lsa_refresh, lsa,
+ 0, &lsa->refresh);
}
}
}
SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE);
/* Redo summaries if required */
- thread_execute(master, ospf6_abr_task_timer, ospf6, 0);
+ event_execute(master, ospf6_abr_task_timer, ospf6, 0);
}
ospf6_route_remove(range, oa->nssa_range_table);
}
/* Register OSPFv3-MIB. */
-static int ospf6_snmp_init(struct thread_master *master)
+static int ospf6_snmp_init(struct event_loop *master)
{
smux_init(master);
REGISTER_MIB("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
#include "vty.h"
#include "prefix.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "lib_errors.h"
#include "ospf6_lsa.h"
zlog_debug("%s", buffer);
}
-static void ospf6_spf_calculation_thread(struct thread *t)
+static void ospf6_spf_calculation_thread(struct event *t)
{
struct ospf6_area *oa;
struct ospf6 *ospf6;
int areas_processed = 0;
char rbuf[32];
- ospf6 = (struct ospf6 *)THREAD_ARG(t);
+ ospf6 = (struct ospf6 *)EVENT_ARG(t);
/* execute SPF calculation */
monotime(&start);
}
/* SPF calculation timer is already scheduled. */
- if (thread_is_scheduled(ospf6->t_spf_calc)) {
+ if (event_is_scheduled(ospf6->t_spf_calc)) {
if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME))
zlog_debug(
"SPF: calculation timer is already scheduled: %p",
if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME))
zlog_debug("SPF: Rescheduling in %ld msec", delay);
- THREAD_OFF(ospf6->t_spf_calc);
- thread_add_timer_msec(master, ospf6_spf_calculation_thread, ospf6,
- delay, &ospf6->t_spf_calc);
+ EVENT_OFF(ospf6->t_spf_calc);
+ event_add_timer_msec(master, ospf6_spf_calculation_thread, ospf6, delay,
+ &ospf6->t_spf_calc);
}
void ospf6_spf_display_subtree(struct vty *vty, const char *prefix, int rest,
return 0;
}
-static void ospf6_ase_calculate_timer(struct thread *t)
+static void ospf6_ase_calculate_timer(struct event *t)
{
struct ospf6 *ospf6;
struct ospf6_lsa *lsa;
struct ospf6_area *area;
uint16_t type;
- ospf6 = THREAD_ARG(t);
+ ospf6 = EVENT_ARG(t);
/* Calculate external route for each AS-external-LSA */
type = htons(OSPF6_LSTYPE_AS_EXTERNAL);
if (ospf6 == NULL)
return;
- thread_add_timer(master, ospf6_ase_calculate_timer, ospf6,
- OSPF6_ASE_CALC_INTERVAL, &ospf6->t_ase_calc);
+ event_add_timer(master, ospf6_ase_calculate_timer, ospf6,
+ OSPF6_ASE_CALC_INTERVAL, &ospf6->t_ase_calc);
}
#include "linklist.h"
#include "prefix.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "defaults.h"
#include "lib/json.h"
* from VRF and make it "down".
*/
ospf6_vrf_unlink(ospf6, vrf);
- thread_cancel(&ospf6->t_ospf6_receive);
+ event_cancel(&ospf6->t_ospf6_receive);
close(ospf6->fd);
ospf6->fd = -1;
}
ret = ospf6_serv_sock(ospf6);
if (ret < 0 || ospf6->fd <= 0)
return 0;
- thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
- &ospf6->t_ospf6_receive);
+ event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
+ &ospf6->t_ospf6_receive);
ospf6_router_id_update(ospf6, true);
}
*/
ospf6_gr_nvm_read(ospf6);
- thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
- &ospf6->t_ospf6_receive);
+ event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
+ &ospf6->t_ospf6_receive);
return ospf6;
}
ospf6_route_remove_all(o->route_table);
ospf6_route_remove_all(o->brouter_table);
- THREAD_OFF(o->maxage_remover);
- THREAD_OFF(o->t_spf_calc);
- THREAD_OFF(o->t_ase_calc);
- THREAD_OFF(o->t_distribute_update);
- THREAD_OFF(o->t_ospf6_receive);
- THREAD_OFF(o->t_external_aggr);
- THREAD_OFF(o->gr_info.t_grace_period);
- THREAD_OFF(o->t_write);
- THREAD_OFF(o->t_abr_task);
+ EVENT_OFF(o->maxage_remover);
+ EVENT_OFF(o->t_spf_calc);
+ EVENT_OFF(o->t_ase_calc);
+ EVENT_OFF(o->t_distribute_update);
+ EVENT_OFF(o->t_ospf6_receive);
+ EVENT_OFF(o->t_external_aggr);
+ EVENT_OFF(o->gr_info.t_grace_period);
+ EVENT_OFF(o->t_write);
+ EVENT_OFF(o->t_abr_task);
}
}
-void ospf6_master_init(struct thread_master *master)
+void ospf6_master_init(struct event_loop *master)
{
memset(&ospf6_master, 0, sizeof(ospf6_master));
om6->master = master;
}
-static void ospf6_maxage_remover(struct thread *thread)
+static void ospf6_maxage_remover(struct event *thread)
{
- struct ospf6 *o = (struct ospf6 *)THREAD_ARG(thread);
+ struct ospf6 *o = (struct ospf6 *)EVENT_ARG(thread);
struct ospf6_area *oa;
struct ospf6_interface *oi;
struct ospf6_neighbor *on;
void ospf6_maxage_remove(struct ospf6 *o)
{
if (o)
- thread_add_timer(master, ospf6_maxage_remover, o,
- OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
- &o->maxage_remover);
+ event_add_timer(master, ospf6_maxage_remover, o,
+ OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
+ &o->maxage_remover);
}
bool ospf6_router_id_update(struct ospf6 *ospf6, bool init)
} else
json_object_boolean_false_add(json, "spfHasRun");
- if (thread_is_scheduled(o->t_spf_calc)) {
+ if (event_is_scheduled(o->t_spf_calc)) {
long time_store;
json_object_boolean_true_add(json, "spfTimerActive");
threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
vty_out(vty, " SPF timer %s%s\n",
- (thread_is_scheduled(o->t_spf_calc) ? "due in "
- : "is "),
+ (event_is_scheduled(o->t_spf_calc) ? "due in " : "is "),
buf);
if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
/* OSPFv3 instance. */
struct list *ospf6;
/* OSPFv3 thread master. */
- struct thread_master *master;
+ struct event_loop *master;
};
/* ospf6->config_flags */
bool prepare_in_progress;
bool finishing_restart;
uint32_t grace_period;
- struct thread *t_grace_period;
+ struct event *t_grace_period;
};
struct ospf6_gr_helper {
int fd;
/* Threads */
- struct thread *t_spf_calc; /* SPF calculation timer. */
- struct thread *t_ase_calc; /* ASE calculation timer. */
- struct thread *maxage_remover;
- struct thread *t_distribute_update; /* Distirbute update timer. */
- struct thread *t_ospf6_receive; /* OSPF6 receive timer */
- struct thread *t_external_aggr; /* OSPF6 aggregation timer */
+ struct event *t_spf_calc; /* SPF calculation timer. */
+ struct event *t_ase_calc; /* ASE calculation timer. */
+ struct event *maxage_remover;
+ struct event *t_distribute_update; /* Distirbute update timer. */
+ struct event *t_ospf6_receive; /* OSPF6 receive timer */
+ struct event *t_external_aggr; /* OSPF6 aggregation timer */
#define OSPF6_WRITE_INTERFACE_COUNT_DEFAULT 20
- struct thread *t_write;
+ struct event *t_write;
int write_oi_count; /* Num of packets sent per thread invocation */
uint32_t ref_bandwidth;
/* Count of NSSA areas */
uint8_t anyNSSA;
- struct thread *t_abr_task; /* ABR task timer. */
+ struct event *t_abr_task; /* ABR task timer. */
struct list *oi_write_q;
uint32_t redist_count;
extern struct ospf6_master *om6;
/* prototypes */
-extern void ospf6_master_init(struct thread_master *master);
+extern void ospf6_master_init(struct event_loop *master);
extern void install_element_ospf6_clear_process(void);
extern void ospf6_top_init(void);
extern void ospf6_delete(struct ospf6 *o);
[ZEBRA_NEXTHOP_UPDATE] = ospf6_zebra_import_check_update,
};
-void ospf6_zebra_init(struct thread_master *master)
+void ospf6_zebra_init(struct event_loop *master)
{
/* Allocate zebra structure. */
zclient = zclient_new(master, &zclient_options_default, ospf6_handlers,
extern void ospf6_zebra_no_redistribute(int, vrf_id_t vrf_id);
#define ospf6_zebra_is_redistribute(type, vrf_id) \
vrf_bitmap_check(zclient->redist[AFI_IP6][type], vrf_id)
-extern void ospf6_zebra_init(struct thread_master *tm);
+extern void ospf6_zebra_init(struct event_loop *tm);
extern void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg);
extern void ospf6_zebra_add_discard(struct ospf6_route *request,
struct ospf6 *ospf6);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "command.h"
}
/* Install ospf related commands. */
-void ospf6_init(struct thread_master *master)
+void ospf6_init(struct event_loop *master)
{
ospf6_top_init();
ospf6_area_init();
#define OSPF6D_H
#include "libospf.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
DECLARE_MGROUP(OSPF6D);
/* global variables */
-extern struct thread_master *master;
+extern struct event_loop *master;
/* Historical for KAME. */
#ifndef IPV6_JOIN_GROUP
extern struct route_node *route_prev(struct route_node *node);
extern void ospf6_debug(void);
-extern void ospf6_init(struct thread_master *master);
+extern void ospf6_init(struct event_loop *master);
#endif /* OSPF6D_H */
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "linklist.h"
#include "if.h"
free to use any thread library (like pthreads). */
#include "ospfd/ospf_dump.h" /* for ospf_lsa_header_dump */
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
/* Local portnumber for async channel. Note that OSPF API library will also
#define ASYNCPORT 4000
/* Master thread */
-struct thread_master *master;
+struct event_loop *master;
/* Global variables */
struct ospf_apiclient *oclient;
* ---------------------------------------------------------
*/
-static void lsa_delete(struct thread *t)
+static void lsa_delete(struct event *t)
{
struct ospf_apiclient *oclient;
struct in_addr area_id;
int rc;
- oclient = THREAD_ARG(t);
+ oclient = EVENT_ARG(t);
rc = inet_aton(args[6], &area_id);
if (rc <= 0) {
printf("done, return code is = %d\n", rc);
}
-static void lsa_inject(struct thread *t)
+static void lsa_inject(struct event *t)
{
struct ospf_apiclient *cl;
struct in_addr ifaddr;
static uint32_t counter = 1; /* Incremented each time invoked */
int rc;
- cl = THREAD_ARG(t);
+ cl = EVENT_ARG(t);
rc = inet_aton(args[5], &ifaddr);
if (rc <= 0) {
/* This thread handles asynchronous messages coming in from the OSPF
API server */
-static void lsa_read(struct thread *thread)
+static void lsa_read(struct event *thread)
{
struct ospf_apiclient *oclient;
int fd;
printf("lsa_read called\n");
- oclient = THREAD_ARG(thread);
- fd = THREAD_FD(thread);
+ oclient = EVENT_ARG(thread);
+ fd = EVENT_FD(thread);
/* Handle asynchronous message */
ret = ospf_apiclient_handle_async(oclient);
}
/* Reschedule read thread */
- thread_add_read(master, lsa_read, oclient, fd, NULL);
+ event_add_read(master, lsa_read, oclient, fd, NULL);
}
/* ---------------------------------------------------------
lsa_type, opaque_type, &addr);
/* Schedule opaque LSA originate in 5 secs */
- thread_add_timer(master, lsa_inject, oclient, 5, NULL);
+ event_add_timer(master, lsa_inject, oclient, 5, NULL);
/* Schedule opaque LSA update with new value */
- thread_add_timer(master, lsa_inject, oclient, 10, NULL);
+ event_add_timer(master, lsa_inject, oclient, 10, NULL);
/* Schedule delete */
- thread_add_timer(master, lsa_delete, oclient, 30, NULL);
+ event_add_timer(master, lsa_delete, oclient, 30, NULL);
}
static void new_if_callback(struct in_addr ifaddr, struct in_addr area_id)
int main(int argc, char *argv[])
{
- struct thread thread;
+ struct event thread;
args = argv;
/* Initialization */
zprivs_preinit(&ospfd_privs);
zprivs_init(&ospfd_privs);
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
/* Open connection to OSPF daemon */
oclient = ospf_apiclient_connect(args[1], ASYNCPORT);
ospf_apiclient_sync_lsdb(oclient);
/* Schedule thread that handles asynchronous messages */
- thread_add_read(master, lsa_read, oclient, oclient->fd_async, NULL);
+ event_add_read(master, lsa_read, oclient, oclient->fd_async, NULL);
/* Now connection is established, run loop */
while (1) {
- thread_fetch(master, &thread);
- thread_call(&thread);
+ event_fetch(master, &thread);
+ event_call(&thread);
}
/* Never reached */
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
* @param thread
* @return 0.
*/
-static void ospf_abr_announce_non_dna_routers(struct thread *thread)
+static void ospf_abr_announce_non_dna_routers(struct event *thread)
{
struct ospf_area *area;
struct listnode *node;
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
- THREAD_OFF(ospf->t_abr_fr);
+ EVENT_OFF(ospf->t_abr_fr);
if (!IS_OSPF_ABR(ospf))
return;
* giving time for route synchronization in
* all the routers.
*/
- thread_add_timer(
- master, ospf_abr_announce_non_dna_routers, ospf,
- OSPF_ABR_DNA_TIMER, &ospf->t_abr_fr);
+ event_add_timer(master,
+ ospf_abr_announce_non_dna_routers, ospf,
+ OSPF_ABR_DNA_TIMER, &ospf->t_abr_fr);
}
}
zlog_debug("%s: Stop", __func__);
}
-static void ospf_abr_task_timer(struct thread *thread)
+static void ospf_abr_task_timer(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
ospf->t_abr_task = 0;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Scheduling ABR task");
- thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY,
- &ospf->t_abr_task);
+ event_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY,
+ &ospf->t_abr_task);
}
#include "vty.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "buffer.h"
#include "vty.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "buffer.h"
#include <sys/types.h>
-#include "ospfd/ospfd.h" /* for "struct thread_master" */
+#include "ospfd/ospfd.h" /* for "struct event_loop" */
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
{
switch (event) {
case OSPF_APISERVER_ACCEPT:
- (void)thread_add_read(master, ospf_apiserver_accept, apiserv,
- fd, NULL);
+ (void)event_add_read(master, ospf_apiserver_accept, apiserv, fd,
+ NULL);
break;
case OSPF_APISERVER_SYNC_READ:
apiserv->t_sync_read = NULL;
- thread_add_read(master, ospf_apiserver_read, apiserv, fd,
- &apiserv->t_sync_read);
+ event_add_read(master, ospf_apiserver_read, apiserv, fd,
+ &apiserv->t_sync_read);
break;
#ifdef USE_ASYNC_READ
case OSPF_APISERVER_ASYNC_READ:
apiserv->t_async_read = NULL;
- thread_add_read(master, ospf_apiserver_read, apiserv, fd,
- &apiserv->t_async_read);
+ event_add_read(master, ospf_apiserver_read, apiserv, fd,
+ &apiserv->t_async_read);
break;
#endif /* USE_ASYNC_READ */
case OSPF_APISERVER_SYNC_WRITE:
- thread_add_write(master, ospf_apiserver_sync_write, apiserv, fd,
- &apiserv->t_sync_write);
+ event_add_write(master, ospf_apiserver_sync_write, apiserv, fd,
+ &apiserv->t_sync_write);
break;
case OSPF_APISERVER_ASYNC_WRITE:
- thread_add_write(master, ospf_apiserver_async_write, apiserv,
- fd, &apiserv->t_async_write);
+ event_add_write(master, ospf_apiserver_async_write, apiserv, fd,
+ &apiserv->t_async_write);
break;
}
}
struct listnode *node;
/* Cancel read and write threads. */
- THREAD_OFF(apiserv->t_sync_read);
+ EVENT_OFF(apiserv->t_sync_read);
#ifdef USE_ASYNC_READ
- THREAD_OFF(apiserv->t_async_read);
+ EVENT_OFF(apiserv->t_async_read);
#endif /* USE_ASYNC_READ */
- THREAD_OFF(apiserv->t_sync_write);
- THREAD_OFF(apiserv->t_async_write);
+ EVENT_OFF(apiserv->t_sync_write);
+ EVENT_OFF(apiserv->t_async_write);
/* Unregister all opaque types that application registered
and flush opaque LSAs if still in LSDB. */
XFREE(MTYPE_APISERVER, apiserv);
}
-void ospf_apiserver_read(struct thread *thread)
+void ospf_apiserver_read(struct event *thread)
{
struct ospf_apiserver *apiserv;
struct msg *msg;
int fd;
enum ospf_apiserver_event event;
- apiserv = THREAD_ARG(thread);
- fd = THREAD_FD(thread);
+ apiserv = EVENT_ARG(thread);
+ fd = EVENT_FD(thread);
if (fd == apiserv->fd_sync) {
event = OSPF_APISERVER_SYNC_READ;
msg_free(msg);
}
-void ospf_apiserver_sync_write(struct thread *thread)
+void ospf_apiserver_sync_write(struct event *thread)
{
struct ospf_apiserver *apiserv;
struct msg *msg;
int fd;
int rc = -1;
- apiserv = THREAD_ARG(thread);
+ apiserv = EVENT_ARG(thread);
assert(apiserv);
- fd = THREAD_FD(thread);
+ fd = EVENT_FD(thread);
apiserv->t_sync_write = NULL;
}
-void ospf_apiserver_async_write(struct thread *thread)
+void ospf_apiserver_async_write(struct event *thread)
{
struct ospf_apiserver *apiserv;
struct msg *msg;
int fd;
int rc = -1;
- apiserv = THREAD_ARG(thread);
+ apiserv = EVENT_ARG(thread);
assert(apiserv);
- fd = THREAD_FD(thread);
+ fd = EVENT_FD(thread);
apiserv->t_async_write = NULL;
/* Accept connection request from external applications. For each
accepted connection allocate own connection instance. */
-void ospf_apiserver_accept(struct thread *thread)
+void ospf_apiserver_accept(struct event *thread)
{
int accept_sock;
int new_sync_sock;
unsigned int peerlen;
int ret;
- /* THREAD_ARG (thread) is NULL */
- accept_sock = THREAD_FD(thread);
+ /* EVENT_ARG (thread) is NULL */
+ accept_sock = EVENT_FD(thread);
/* Keep hearing on socket for further connections. */
ospf_apiserver_event(OSPF_APISERVER_ACCEPT, accept_sock, NULL);
struct msg_fifo *out_async_fifo;
/* Read and write threads */
- struct thread *t_sync_read;
+ struct event *t_sync_read;
#ifdef USE_ASYNC_READ
- struct thread *t_async_read;
+ struct event *t_async_read;
#endif /* USE_ASYNC_READ */
- struct thread *t_sync_write;
- struct thread *t_async_write;
+ struct event *t_sync_write;
+ struct event *t_async_write;
};
enum ospf_apiserver_event {
extern void ospf_apiserver_event(enum ospf_apiserver_event event, int fd,
struct ospf_apiserver *apiserv);
extern int ospf_apiserver_serv_sock_family(unsigned short port, int family);
-extern void ospf_apiserver_accept(struct thread *thread);
-extern void ospf_apiserver_read(struct thread *thread);
-extern void ospf_apiserver_sync_write(struct thread *thread);
-extern void ospf_apiserver_async_write(struct thread *thread);
+extern void ospf_apiserver_accept(struct event *thread);
+extern void ospf_apiserver_read(struct event *thread);
+extern void ospf_apiserver_sync_write(struct event *thread);
+extern void ospf_apiserver_async_write(struct event *thread);
extern int ospf_apiserver_send_reply(struct ospf_apiserver *apiserv,
uint32_t seqnr, uint8_t rc);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
/* If there's redistribution configured, we need to refresh external
* LSAs in order to install Type-7 and flood to all NSSA Areas
*/
-static void ospf_asbr_nssa_redist_update_timer(struct thread *thread)
+static void ospf_asbr_nssa_redist_update_timer(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
int type;
ospf->t_asbr_nssa_redist_update = NULL;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Scheduling ASBR NSSA redistribution update");
- thread_add_timer(master, ospf_asbr_nssa_redist_update_timer, ospf,
- OSPF_ASBR_NSSA_REDIST_UPDATE_DELAY,
- &ospf->t_asbr_nssa_redist_update);
+ event_add_timer(master, ospf_asbr_nssa_redist_update_timer, ospf,
+ OSPF_ASBR_NSSA_REDIST_UPDATE_DELAY,
+ &ospf->t_asbr_nssa_redist_update);
}
void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type,
void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr)
{
- if (OSPF_EXTERNAL_RT_COUNT(aggr))
- hash_clean(aggr->match_extnl_hash,
- (void *)ospf_aggr_unlink_external_info);
+ hash_clean_and_free(&aggr->match_extnl_hash,
+ (void *)ospf_aggr_unlink_external_info);
if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
zlog_debug("%s: Release the aggregator Address(%pI4/%d)",
__func__, &aggr->p.prefix, aggr->p.prefixlen);
- hash_free(aggr->match_extnl_hash);
- aggr->match_extnl_hash = NULL;
XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr);
}
aggr->action = OSPF_ROUTE_AGGR_NONE;
ospf_external_aggr_delete(ospf, rn);
- if (OSPF_EXTERNAL_RT_COUNT(aggr))
- hash_clean(
- aggr->match_extnl_hash,
- (void *)ospf_aggr_handle_external_info);
-
- hash_free(aggr->match_extnl_hash);
- XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr);
+ hash_clean_and_free(
+ &aggr->match_extnl_hash,
+ (void *)ospf_aggr_handle_external_info);
} else if (aggr->action == OSPF_ROUTE_AGGR_MODIFY) {
}
}
-static void ospf_asbr_external_aggr_process(struct thread *thread)
+static void ospf_asbr_external_aggr_process(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
int operation = 0;
ospf->t_external_aggr = NULL;
zlog_debug(
"%s, Restarting Aggregator delay timer.",
__func__);
- THREAD_OFF(ospf->t_external_aggr);
+ EVENT_OFF(ospf->t_external_aggr);
}
}
__func__, ospf->aggr_delay_interval);
ospf->aggr_action = operation;
- thread_add_timer(master, ospf_asbr_external_aggr_process, ospf,
- ospf->aggr_delay_interval, &ospf->t_external_aggr);
+ event_add_timer(master, ospf_asbr_external_aggr_process, ospf,
+ ospf->aggr_delay_interval, &ospf->t_external_aggr);
}
int ospf_asbr_external_aggregator_set(struct ospf *ospf, struct prefix_ipv4 *p,
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "hash.h"
#include "linklist.h"
return 0;
}
-static void ospf_ase_calculate_timer(struct thread *t)
+static void ospf_ase_calculate_timer(struct event *t)
{
struct ospf *ospf;
struct ospf_lsa *lsa;
struct ospf_area *area;
struct timeval start_time, stop_time;
- ospf = THREAD_ARG(t);
+ ospf = EVENT_ARG(t);
ospf->t_ase_calc = NULL;
if (ospf->ase_calc) {
if (ospf == NULL)
return;
- thread_add_timer(master, ospf_ase_calculate_timer, ospf,
- OSPF_ASE_CALC_INTERVAL, &ospf->t_ase_calc);
+ event_add_timer(master, ospf_ase_calculate_timer, ospf,
+ OSPF_ASE_CALC_INTERVAL, &ospf->t_ase_calc);
}
void ospf_ase_register_external_lsa(struct ospf_lsa *lsa, struct ospf *top)
#include "linklist.h"
#include "memory.h"
#include "prefix.h"
-#include "thread.h"
+#include "frrevent.h"
#include "buffer.h"
#include "stream.h"
#include "zclient.h"
return CMD_SUCCESS;
}
-void ospf_bfd_init(struct thread_master *tm)
+void ospf_bfd_init(struct event_loop *tm)
{
bfd_protocol_integration_init(zclient, tm);
#include "ospfd/ospf_interface.h"
#include "json.h"
-extern void ospf_bfd_init(struct thread_master *tm);
+extern void ospf_bfd_init(struct event_loop *tm);
extern void ospf_bfd_write_config(struct vty *vty,
const struct ospf_if_params *params);
#include "lib/bfd.h"
#include "monotime.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "command.h"
#include "stream.h"
return buf;
}
-const char *ospf_timer_dump(struct thread *t, char *buf, size_t size)
+const char *ospf_timer_dump(struct event *t, char *buf, size_t size)
{
struct timeval result;
if (!t)
extern char *ospf_lsa_type_str[];
/* Prototypes. */
-extern const char *ospf_area_name_string(struct ospf_area *);
-extern const char *ospf_area_desc_string(struct ospf_area *);
-extern const char *ospf_if_name_string(struct ospf_interface *);
+extern const char *ospf_area_name_string(struct ospf_area *area);
+extern const char *ospf_area_desc_string(struct ospf_area *area);
+extern const char *ospf_if_name_string(struct ospf_interface *oip);
extern int ospf_nbr_ism_state(struct ospf_neighbor *nbr);
extern void ospf_nbr_ism_state_message(struct ospf_neighbor *nbr, char *buf,
size_t size);
-extern const char *ospf_timer_dump(struct thread *, char *, size_t);
-extern const char *ospf_timeval_dump(struct timeval *, char *, size_t);
-extern void ospf_packet_dump(struct stream *);
+extern const char *ospf_timer_dump(struct event *e, char *buf, size_t size);
+extern const char *ospf_timeval_dump(struct timeval *t, char *buf, size_t size);
+extern void ospf_packet_dump(struct stream *s);
extern void ospf_debug_init(void);
/* Appropriate buffer size to use with ospf_timer_dump and ospf_timeval_dump: */
#include "vty.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "network.h"
#include "if.h"
#include "command.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "log.h"
#include "zclient.h"
zlog_debug("GR: exiting graceful restart: %s", reason);
ospf->gr_info.restart_in_progress = false;
- THREAD_OFF(ospf->gr_info.t_grace_period);
+ EVENT_OFF(ospf->gr_info.t_grace_period);
/* Record in non-volatile memory that the restart is complete. */
ospf_gr_nvm_delete(ospf);
}
/* Handling of grace period expiry. */
-static void ospf_gr_grace_period_expired(struct thread *thread)
+static void ospf_gr_grace_period_expired(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
ospf->gr_info.t_grace_period = NULL;
ospf_gr_restart_exit(ospf, "grace period has expired");
zlog_debug(
"GR: remaining time until grace period expires: %lu(s)",
remaining_time);
- thread_add_timer(master, ospf_gr_grace_period_expired,
- ospf, remaining_time,
- &ospf->gr_info.t_grace_period);
+ event_add_timer(master, ospf_gr_grace_period_expired,
+ ospf, remaining_time,
+ &ospf->gr_info.t_grace_period);
}
}
* helper until this timer until
* this timer expires.
*/
- struct thread *t_grace_timer;
+ struct event *t_grace_timer;
/* Helper status */
uint32_t gr_helper_status;
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
if (ospf->enable_rtr_list == NULL)
return;
- hash_clean(ospf->enable_rtr_list, ospf_disable_rtr_hash_free);
- hash_free(ospf->enable_rtr_list);
- ospf->enable_rtr_list = NULL;
+ hash_clean_and_free(&ospf->enable_rtr_list, ospf_disable_rtr_hash_free);
}
/*
* Returns:
* Nothing
*/
-static void ospf_handle_grace_timer_expiry(struct thread *thread)
+static void ospf_handle_grace_timer_expiry(struct event *thread)
{
- struct ospf_neighbor *nbr = THREAD_ARG(thread);
+ struct ospf_neighbor *nbr = EVENT_ARG(thread);
nbr->gr_helper_info.t_grace_timer = NULL;
if (OSPF_GR_IS_ACTIVE_HELPER(restarter)) {
if (restarter->gr_helper_info.t_grace_timer)
- THREAD_OFF(restarter->gr_helper_info.t_grace_timer);
+ EVENT_OFF(restarter->gr_helper_info.t_grace_timer);
if (ospf->active_restarter_cnt > 0)
ospf->active_restarter_cnt--;
actual_grace_interval);
/* Start the grace timer */
- thread_add_timer(master, ospf_handle_grace_timer_expiry, restarter,
- actual_grace_interval,
- &restarter->gr_helper_info.t_grace_timer);
+ event_add_timer(master, ospf_handle_grace_timer_expiry, restarter,
+ actual_grace_interval,
+ &restarter->gr_helper_info.t_grace_timer);
return OSPF_GR_ACTIVE_HELPER;
}
* expiry, stop the grace timer.
*/
if (reason != OSPF_GR_HELPER_GRACE_TIMEOUT)
- THREAD_OFF(nbr->gr_helper_info.t_grace_timer);
+ EVENT_OFF(nbr->gr_helper_info.t_grace_timer);
/* check exit triggered due to successful completion
* of graceful restart.
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "hash.h"
#include "linklist.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
/* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
/* delete all static neighbors attached to this interface */
for (ALL_LIST_ELEMENTS(oi->nbr_nbma, node, nnode, nbr_nbma)) {
- THREAD_OFF(nbr_nbma->t_poll);
+ EVENT_OFF(nbr_nbma->t_poll);
if (nbr_nbma->nbr) {
nbr_nbma->nbr->nbr_nbma = NULL;
listnode_delete(oi->ospf->oiflist, oi);
listnode_delete(oi->area->oiflist, oi);
- thread_cancel_event(master, oi);
+ event_cancel_event(master, oi);
memset(oi, 0, sizeof(*oi));
XFREE(MTYPE_OSPF_IF, oi);
if (oi->on_write_q) {
listnode_delete(ospf->oi_write_q, oi);
if (list_isempty(ospf->oi_write_q))
- THREAD_OFF(ospf->t_write);
+ EVENT_OFF(ospf->t_write);
oi->on_write_q = 0;
}
}
if_delete(&ifp);
if (!vrf_is_enabled(vrf))
vrf_delete(vrf);
- vlink_count--;
}
/* for a defined area, count the number of configured vl
ospf_hello_send(oi);
/* Restart hello timer for this interface */
- THREAD_OFF(oi->t_hello);
+ EVENT_OFF(oi->t_hello);
OSPF_HELLO_TIMER_ON(oi);
}
ospf_hello_send(oi);
/* Restart the hello timer. */
- THREAD_OFF(oi->t_hello);
+ EVENT_OFF(oi->t_hello);
OSPF_HELLO_TIMER_ON(oi);
}
}
uint32_t v_ls_ack; /* Delayed Link State Acknowledgment */
/* Threads. */
- struct thread *t_hello; /* timer */
- struct thread *t_wait; /* timer */
- struct thread *t_ls_ack; /* timer */
- struct thread *t_ls_ack_direct; /* event */
- struct thread *t_ls_upd_event; /* event */
- struct thread *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */
+ struct event *t_hello; /* timer */
+ struct event *t_wait; /* timer */
+ struct event *t_ls_ack; /* timer */
+ struct event *t_ls_ack_direct; /* event */
+ struct event *t_ls_upd_event; /* event */
+ struct event *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */
int on_write_q;
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
}
-void ospf_hello_timer(struct thread *thread)
+void ospf_hello_timer(struct event *thread)
{
struct ospf_interface *oi;
- oi = THREAD_ARG(thread);
+ oi = EVENT_ARG(thread);
oi->t_hello = NULL;
if (IS_DEBUG_OSPF(ism, ISM_TIMERS))
OSPF_HELLO_TIMER_ON(oi);
}
-static void ospf_wait_timer(struct thread *thread)
+static void ospf_wait_timer(struct event *thread)
{
struct ospf_interface *oi;
- oi = THREAD_ARG(thread);
+ oi = EVENT_ARG(thread);
oi->t_wait = NULL;
if (IS_DEBUG_OSPF(ism, ISM_TIMERS))
interface parameters must be set to initial values, and
timers are
reset also. */
- THREAD_OFF(oi->t_hello);
- THREAD_OFF(oi->t_wait);
- THREAD_OFF(oi->t_ls_ack);
+ EVENT_OFF(oi->t_hello);
+ EVENT_OFF(oi->t_wait);
+ EVENT_OFF(oi->t_ls_ack);
break;
case ISM_Loopback:
/* In this state, the interface may be looped back and will be
unavailable for regular data traffic. */
- THREAD_OFF(oi->t_hello);
- THREAD_OFF(oi->t_wait);
- THREAD_OFF(oi->t_ls_ack);
+ EVENT_OFF(oi->t_hello);
+ EVENT_OFF(oi->t_wait);
+ EVENT_OFF(oi->t_ls_ack);
break;
case ISM_Waiting:
/* The router is trying to determine the identity of DRouter and
OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1);
OSPF_ISM_TIMER_ON(oi->t_wait, ospf_wait_timer,
OSPF_IF_PARAM(oi, v_wait));
- THREAD_OFF(oi->t_ls_ack);
+ EVENT_OFF(oi->t_ls_ack);
break;
case ISM_PointToPoint:
/* The interface connects to a physical Point-to-point network
neighboring router. Hello packets are also sent. */
/* send first hello immediately */
OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1);
- THREAD_OFF(oi->t_wait);
+ EVENT_OFF(oi->t_wait);
OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
oi->v_ls_ack);
break;
and the router itself is neither Designated Router nor
Backup Designated Router. */
OSPF_HELLO_TIMER_ON(oi);
- THREAD_OFF(oi->t_wait);
+ EVENT_OFF(oi->t_wait);
OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
oi->v_ls_ack);
break;
network,
and the router is Backup Designated Router. */
OSPF_HELLO_TIMER_ON(oi);
- THREAD_OFF(oi->t_wait);
+ EVENT_OFF(oi->t_wait);
OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
oi->v_ls_ack);
break;
network,
and the router is Designated Router. */
OSPF_HELLO_TIMER_ON(oi);
- THREAD_OFF(oi->t_wait);
+ EVENT_OFF(oi->t_wait);
OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
oi->v_ls_ack);
break;
}
/* Execute ISM event process. */
-void ospf_ism_event(struct thread *thread)
+void ospf_ism_event(struct event *thread)
{
int event;
int next_state;
struct ospf_interface *oi;
- oi = THREAD_ARG(thread);
- event = THREAD_VAL(thread);
+ oi = EVENT_ARG(thread);
+ event = EVENT_VAL(thread);
/* Call function. */
next_state = (*(ISM[oi->state][event].func))(oi);
oi->on_write_q = 1; \
} \
if (!list_isempty((O)->oi_write_q)) \
- thread_add_write(master, ospf_write, (O), (O)->fd, \
- &(O)->t_write); \
+ event_add_write(master, ospf_write, (O), (O)->fd, \
+ &(O)->t_write); \
} while (0)
/* Macro for OSPF ISM timer turn on. */
-#define OSPF_ISM_TIMER_ON(T, F, V) thread_add_timer(master, (F), oi, (V), &(T))
+#define OSPF_ISM_TIMER_ON(T, F, V) event_add_timer(master, (F), oi, (V), &(T))
#define OSPF_ISM_TIMER_MSEC_ON(T, F, V) \
- thread_add_timer_msec(master, (F), oi, (V), &(T))
+ event_add_timer_msec(master, (F), oi, (V), &(T))
/* convenience macro to set hello timer correctly, according to
* whether fast-hello is set or not
/* Macro for OSPF schedule event. */
#define OSPF_ISM_EVENT_SCHEDULE(I, E) \
- thread_add_event(master, ospf_ism_event, (I), (E), NULL)
+ event_add_event(master, ospf_ism_event, (I), (E), NULL)
/* Macro for OSPF execute event. */
#define OSPF_ISM_EVENT_EXECUTE(I, E) \
- thread_execute(master, ospf_ism_event, (I), (E))
+ event_execute(master, ospf_ism_event, (I), (E))
/* Prototypes. */
-extern void ospf_ism_event(struct thread *thread);
+extern void ospf_ism_event(struct event *thread);
extern void ism_change_status(struct ospf_interface *, int);
-extern void ospf_hello_timer(struct thread *thread);
+extern void ospf_hello_timer(struct event *thread);
extern int ospf_dr_election(struct ospf_interface *oi);
DECLARE_HOOK(ospf_ism_change,
#include "monotime.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "table.h"
#include "vty.h"
if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP)
ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP;
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
ospf_if_recalculate_output_cost(ifp);
}
}
if (ldp_sync_info &&
ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED &&
ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) {
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
ospf_if_recalculate_output_cost(ifp);
}
*/
ols_debug("%s: Removed from if %s", __func__, ifp->name);
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
ospf_if_recalculate_output_cost(ifp);
/*
* LDP-SYNC holddown timer routines
*/
-static void ospf_ldp_sync_holddown_timer(struct thread *thread)
+static void ospf_ldp_sync_holddown_timer(struct event *thread)
{
struct interface *ifp;
struct ospf_if_params *params;
* didn't receive msg from LDP indicating sync-complete
* restore interface cost to original value
*/
- ifp = THREAD_ARG(thread);
+ ifp = EVENT_ARG(thread);
params = IF_DEF_PARAMS(ifp);
if (params->ldp_sync_info) {
ldp_sync_info = params->ldp_sync_info;
ols_debug("%s: start holddown timer for %s time %d", __func__,
ifp->name, ldp_sync_info->holddown);
- thread_add_timer(master, ospf_ldp_sync_holddown_timer,
- ifp, ldp_sync_info->holddown,
- &ldp_sync_info->t_holddown);
+ event_add_timer(master, ospf_ldp_sync_holddown_timer, ifp,
+ ldp_sync_info->holddown, &ldp_sync_info->t_holddown);
}
/*
SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT;
ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
- THREAD_OFF(ldp_sync_info->t_holddown);
+ EVENT_OFF(ldp_sync_info->t_holddown);
ospf_if_recalculate_output_cost(ifp);
return CMD_SUCCESS;
#include "memory.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "checksum.h"
stream_putw_at(*s, putp, cnt);
}
-static void ospf_stub_router_timer(struct thread *t)
+static void ospf_stub_router_timer(struct event *t)
{
- struct ospf_area *area = THREAD_ARG(t);
+ struct ospf_area *area = EVENT_ARG(t);
area->t_stub_router = NULL;
struct in_addr old_id)
{
struct ospf_lsa *lsa = NULL;
- struct ospf_lsa *new = NULL;
+ struct ospf_lsa *summary_lsa = NULL;
struct summary_lsa *sl = NULL;
struct ospf_area *old_area = NULL;
struct ospf *ospf = area->ospf;
if (type == OSPF_SUMMARY_LSA) {
/*Refresh the LSA with new LSA*/
- ospf_summary_lsa_refresh(ospf, lsa);
+ summary_lsa = ospf_summary_lsa_refresh(ospf, lsa);
- new = ospf_summary_lsa_prepare_and_flood(
- &old_prefix, old_metric, old_area, old_id);
+ ospf_summary_lsa_prepare_and_flood(&old_prefix, old_metric,
+ old_area, old_id);
} else {
/*Refresh the LSA with new LSA*/
- ospf_summary_asbr_lsa_refresh(ospf, lsa);
+ summary_lsa = ospf_summary_asbr_lsa_refresh(ospf, lsa);
- new = ospf_asbr_summary_lsa_prepare_and_flood(
- &old_prefix, old_metric, old_area, old_id);
+ ospf_asbr_summary_lsa_prepare_and_flood(&old_prefix, old_metric,
+ old_area, old_id);
}
- return new;
+ return summary_lsa;
}
/* Originate Summary-LSA. */
}
-void ospf_maxage_lsa_remover(struct thread *thread)
+void ospf_maxage_lsa_remover(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
struct ospf_lsa *lsa, *old;
struct route_node *rn;
int reschedule = 0;
}
/* TODO: maybe convert this function to a work-queue */
- if (thread_should_yield(thread)) {
+ if (event_should_yield(thread)) {
OSPF_TIMER_ON(ospf->t_maxage,
ospf_maxage_lsa_remover, 0);
route_unlock_node(
}
/* Periodical check of MaxAge LSA. */
-void ospf_lsa_maxage_walker(struct thread *thread)
+void ospf_lsa_maxage_walker(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
struct route_node *rn;
struct ospf_lsa *lsa;
struct ospf_area *area;
* without conflicting to other threads.
*/
if (ospf->t_maxage != NULL) {
- THREAD_OFF(ospf->t_maxage);
- thread_execute(master, ospf_maxage_lsa_remover, ospf, 0);
+ EVENT_OFF(ospf->t_maxage);
+ event_execute(master, ospf_maxage_lsa_remover, ospf, 0);
}
return;
struct ospf_lsa *lsa;
};
-static void ospf_lsa_action(struct thread *t)
+static void ospf_lsa_action(struct event *t)
{
struct lsa_action *data;
- data = THREAD_ARG(t);
+ data = EVENT_ARG(t);
if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
zlog_debug("LSA[Action]: Performing scheduled LSA action: %d",
data->area = area;
data->lsa = ospf_lsa_lock(lsa); /* Message / Flood area */
- thread_add_event(master, ospf_lsa_action, data, 0, NULL);
+ event_add_event(master, ospf_lsa_action, data, 0, NULL);
}
void ospf_schedule_lsa_flush_area(struct ospf_area *area, struct ospf_lsa *lsa)
data->area = area;
data->lsa = ospf_lsa_lock(lsa); /* Message / Flush area */
- thread_add_event(master, ospf_lsa_action, data, 0, NULL);
+ event_add_event(master, ospf_lsa_action, data, 0, NULL);
}
}
}
-void ospf_lsa_refresh_walker(struct thread *t)
+void ospf_lsa_refresh_walker(struct event *t)
{
struct list *refresh_list;
struct listnode *node, *nnode;
- struct ospf *ospf = THREAD_ARG(t);
+ struct ospf *ospf = EVENT_ARG(t);
struct ospf_lsa *lsa;
int i;
struct list *lsa_to_refresh = list_new();
}
ospf->t_lsa_refresher = NULL;
- thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
- ospf->lsa_refresh_interval, &ospf->t_lsa_refresher);
+ event_add_timer(master, ospf_lsa_refresh_walker, ospf,
+ ospf->lsa_refresh_interval, &ospf->t_lsa_refresher);
ospf->lsa_refresher_started = monotime(NULL);
for (ALL_LIST_ELEMENTS(lsa_to_refresh, node, nnode, lsa)) {
dna_lsa = ospf_check_dna_lsa(lsa);
if (!dna_lsa) { /* refresh only non-DNA LSAs */
ospf_lsa_refresh(ospf, lsa);
- assert(lsa->lock > 0);
- ospf_lsa_unlock(&lsa); /* lsa_refresh_queue & temp for
- * lsa_to_refresh.
- */
}
+ assert(lsa->lock > 0);
+ ospf_lsa_unlock(&lsa); /* lsa_refresh_queue & temp for
+ * lsa_to_refresh.
+ */
}
list_delete(&lsa_to_refresh);
extern void ospf_lsa_maxage(struct ospf *, struct ospf_lsa *);
extern uint32_t get_metric(uint8_t *);
-extern void ospf_lsa_maxage_walker(struct thread *thread);
+extern void ospf_lsa_maxage_walker(struct event *thread);
extern struct ospf_lsa *ospf_lsa_refresh(struct ospf *, struct ospf_lsa *);
extern void ospf_external_lsa_refresh_default(struct ospf *);
extern void ospf_refresher_register_lsa(struct ospf *, struct ospf_lsa *);
extern void ospf_refresher_unregister_lsa(struct ospf *, struct ospf_lsa *);
-extern void ospf_lsa_refresh_walker(struct thread *thread);
+extern void ospf_lsa_refresh_walker(struct event *thread);
extern void ospf_lsa_maxage_delete(struct ospf *, struct ospf_lsa *);
struct ospf_lsa *lsa);
extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
int type);
-extern void ospf_maxage_lsa_remover(struct thread *thread);
+extern void ospf_maxage_lsa_remover(struct event *thread);
extern bool ospf_check_dna_lsa(const struct ospf_lsa *lsa);
extern void ospf_refresh_area_self_lsas(struct ospf_area *area);
#include <lib/version.h>
#include "bfd.h"
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "linklist.h"
#include "if.h"
/* OSPFd program name */
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
#ifdef SUPPORT_OSPF_API
extern int ospf_apiserver_enable;
#include "prefix.h"
#include "memory.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "stream.h"
#include "table.h"
#include "log.h"
}
/* Cancel all timers. */
- THREAD_OFF(nbr->t_inactivity);
- THREAD_OFF(nbr->t_db_desc);
- THREAD_OFF(nbr->t_ls_req);
- THREAD_OFF(nbr->t_ls_upd);
+ EVENT_OFF(nbr->t_inactivity);
+ EVENT_OFF(nbr->t_db_desc);
+ EVENT_OFF(nbr->t_ls_req);
+ EVENT_OFF(nbr->t_ls_upd);
/* Cancel all events. */ /* Thread lookup cost would be negligible. */
- thread_cancel_event(master, nbr);
+ event_cancel_event(master, nbr);
bfd_sess_free(&nbr->bfd_session);
- THREAD_OFF(nbr->gr_helper_info.t_grace_timer);
+ EVENT_OFF(nbr->gr_helper_info.t_grace_timer);
nbr->oi = NULL;
XFREE(MTYPE_OSPF_NEIGHBOR, nbr);
nbr->nbr_nbma = nbr_nbma;
if (nbr_nbma->t_poll)
- THREAD_OFF(nbr_nbma->t_poll);
+ EVENT_OFF(nbr_nbma->t_poll);
nbr->state_change = nbr_nbma->state_change + 1;
}
uint32_t v_ls_upd;
/* Threads. */
- struct thread *t_inactivity;
- struct thread *t_db_desc;
- struct thread *t_ls_req;
- struct thread *t_ls_upd;
- struct thread *t_hello_reply;
+ struct event *t_inactivity;
+ struct event *t_db_desc;
+ struct event *t_ls_req;
+ struct event *t_ls_upd;
+ struct event *t_hello_reply;
/* NBMA configured neighbour */
struct ospf_nbr_nbma *nbr_nbma;
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "hash.h"
#include "linklist.h"
static void nsm_clear_adj(struct ospf_neighbor *);
/* OSPF NSM Timer functions. */
-static void ospf_inactivity_timer(struct thread *thread)
+static void ospf_inactivity_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_inactivity = NULL;
if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
}
}
-static void ospf_db_desc_timer(struct thread *thread)
+static void ospf_db_desc_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_db_desc = NULL;
if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
switch (nbr->state) {
case NSM_Deleted:
case NSM_Down:
- THREAD_OFF(nbr->t_inactivity);
- THREAD_OFF(nbr->t_hello_reply);
+ EVENT_OFF(nbr->t_inactivity);
+ EVENT_OFF(nbr->t_hello_reply);
/* fallthru */
case NSM_Attempt:
case NSM_Init:
case NSM_TwoWay:
- THREAD_OFF(nbr->t_db_desc);
- THREAD_OFF(nbr->t_ls_upd);
- THREAD_OFF(nbr->t_ls_req);
+ EVENT_OFF(nbr->t_db_desc);
+ EVENT_OFF(nbr->t_ls_upd);
+ EVENT_OFF(nbr->t_ls_req);
break;
case NSM_ExStart:
OSPF_NSM_TIMER_ON(nbr->t_db_desc, ospf_db_desc_timer,
nbr->v_db_desc);
- THREAD_OFF(nbr->t_ls_upd);
- THREAD_OFF(nbr->t_ls_req);
+ EVENT_OFF(nbr->t_ls_upd);
+ EVENT_OFF(nbr->t_ls_req);
break;
case NSM_Exchange:
OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer,
nbr->v_ls_upd);
if (!IS_SET_DD_MS(nbr->dd_flags))
- THREAD_OFF(nbr->t_db_desc);
+ EVENT_OFF(nbr->t_db_desc);
break;
case NSM_Loading:
case NSM_Full:
default:
- THREAD_OFF(nbr->t_db_desc);
+ EVENT_OFF(nbr->t_db_desc);
break;
}
}
static int nsm_hello_received(struct ospf_neighbor *nbr)
{
/* Start or Restart Inactivity Timer. */
- THREAD_OFF(nbr->t_inactivity);
+ EVENT_OFF(nbr->t_inactivity);
OSPF_NSM_TIMER_ON(nbr->t_inactivity, ospf_inactivity_timer,
nbr->v_inactivity);
if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma)
- THREAD_OFF(nbr->nbr_nbma->t_poll);
+ EVENT_OFF(nbr->nbr_nbma->t_poll);
/* Send proactive ARP requests */
if (nbr->state < NSM_Exchange)
static int nsm_start(struct ospf_neighbor *nbr)
{
if (nbr->nbr_nbma)
- THREAD_OFF(nbr->nbr_nbma->t_poll);
+ EVENT_OFF(nbr->nbr_nbma->t_poll);
- THREAD_OFF(nbr->t_inactivity);
+ EVENT_OFF(nbr->t_inactivity);
OSPF_NSM_TIMER_ON(nbr->t_inactivity, ospf_inactivity_timer,
nbr->v_inactivity);
}
/* Execute NSM event process. */
-void ospf_nsm_event(struct thread *thread)
+void ospf_nsm_event(struct event *thread)
{
int event;
int next_state;
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
- event = THREAD_VAL(thread);
+ nbr = EVENT_ARG(thread);
+ event = EVENT_VAL(thread);
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
zlog_debug("NSM[%s:%pI4:%s]: %s (%s)", IF_NAME(nbr->oi),
#define OSPF_NSM_EVENT_MAX 14
/* Macro for OSPF NSM timer turn on. */
-#define OSPF_NSM_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr, (V), &(T))
+#define OSPF_NSM_TIMER_ON(T, F, V) event_add_timer(master, (F), nbr, (V), &(T))
/* Macro for OSPF NSM schedule event. */
#define OSPF_NSM_EVENT_SCHEDULE(N, E) \
- thread_add_event(master, ospf_nsm_event, (N), (E), NULL)
+ event_add_event(master, ospf_nsm_event, (N), (E), NULL)
/* Macro for OSPF NSM execute event. */
#define OSPF_NSM_EVENT_EXECUTE(N, E) \
- thread_execute(master, ospf_nsm_event, (N), (E))
+ event_execute(master, ospf_nsm_event, (N), (E))
/* Prototypes. */
-extern void ospf_nsm_event(struct thread *);
-extern void ospf_check_nbr_loading(struct ospf_neighbor *);
-extern int ospf_db_summary_isempty(struct ospf_neighbor *);
-extern int ospf_db_summary_count(struct ospf_neighbor *);
-extern void ospf_db_summary_clear(struct ospf_neighbor *);
+extern void ospf_nsm_event(struct event *e);
+extern void ospf_check_nbr_loading(struct ospf_neighbor *nbr);
+extern int ospf_db_summary_isempty(struct ospf_neighbor *nbr);
+extern int ospf_db_summary_count(struct ospf_neighbor *nbr);
+extern void ospf_db_summary_clear(struct ospf_neighbor *nbr);
extern int nsm_should_adj(struct ospf_neighbor *nbr);
DECLARE_HOOK(ospf_nsm_change,
(struct ospf_neighbor * on, int state, int oldstate),
#include "vty.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "printfrr.h"
void ospf_opaque_type9_lsa_term(struct ospf_interface *oi)
{
- THREAD_OFF(oi->t_opaque_lsa_self);
+ EVENT_OFF(oi->t_opaque_lsa_self);
if (oi->opaque_lsa_self != NULL)
list_delete(&oi->opaque_lsa_self);
oi->opaque_lsa_self = NULL;
area->lsdb->new_lsa_hook = area->lsdb->del_lsa_hook = NULL;
#endif /* MONITOR_LSDB_CHANGE */
- THREAD_OFF(area->t_opaque_lsa_self);
+ EVENT_OFF(area->t_opaque_lsa_self);
if (area->opaque_lsa_self != NULL)
list_delete(&area->opaque_lsa_self);
return;
top->lsdb->new_lsa_hook = top->lsdb->del_lsa_hook = NULL;
#endif /* MONITOR_LSDB_CHANGE */
- THREAD_OFF(top->t_opaque_lsa_self);
+ EVENT_OFF(top->t_opaque_lsa_self);
if (top->opaque_lsa_self != NULL)
list_delete(&top->opaque_lsa_self);
return;
* to (re-)originate their own Opaque-LSAs out-of-sync with others.
* This thread is prepared for that specific purpose.
*/
- struct thread *t_opaque_lsa_self;
+ struct event *t_opaque_lsa_self;
/*
* Backpointer to an "owner" which is LSA-type dependent.
uint32_t opaque_id;
/* Thread for refresh/flush scheduling for this opaque-type/id. */
- struct thread *t_opaque_lsa_self;
+ struct event *t_opaque_lsa_self;
/* Backpointer to Opaque-LSA control information per opaque-type. */
struct opaque_info_per_type *opqctl_type;
ospf_opaque_lsa_flush_schedule(lsa);
}
- THREAD_OFF(oipt->t_opaque_lsa_self);
+ EVENT_OFF(oipt->t_opaque_lsa_self);
list_delete(&oipt->id_list);
if (cleanup_owner) {
/* Remove from its owner's self-originated LSA list. */
{
struct opaque_info_per_id *oipi = (struct opaque_info_per_id *)val;
- THREAD_OFF(oipi->t_opaque_lsa_self);
+ EVENT_OFF(oipi->t_opaque_lsa_self);
if (oipi->lsa != NULL)
ospf_lsa_unlock(&oipi->lsa);
XFREE(MTYPE_OPAQUE_INFO_PER_ID, oipi);
* Following are Opaque-LSA origination/refresh management functions.
*------------------------------------------------------------------------*/
-static void ospf_opaque_type9_lsa_originate(struct thread *t);
-static void ospf_opaque_type10_lsa_originate(struct thread *t);
-static void ospf_opaque_type11_lsa_originate(struct thread *t);
+static void ospf_opaque_type9_lsa_originate(struct event *t);
+static void ospf_opaque_type10_lsa_originate(struct event *t);
+static void ospf_opaque_type11_lsa_originate(struct event *t);
static void ospf_opaque_lsa_reoriginate_resume(struct list *listtop, void *arg);
void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, int *delay0)
"Schedule Type-9 Opaque-LSA origination in %d ms later.",
delay);
oi->t_opaque_lsa_self = NULL;
- thread_add_timer_msec(master, ospf_opaque_type9_lsa_originate,
- oi, delay, &oi->t_opaque_lsa_self);
+ event_add_timer_msec(master, ospf_opaque_type9_lsa_originate,
+ oi, delay, &oi->t_opaque_lsa_self);
delay += top->min_ls_interval;
}
"Schedule Type-10 Opaque-LSA origination in %d ms later.",
delay);
area->t_opaque_lsa_self = NULL;
- thread_add_timer_msec(master, ospf_opaque_type10_lsa_originate,
- area, delay, &area->t_opaque_lsa_self);
+ event_add_timer_msec(master, ospf_opaque_type10_lsa_originate,
+ area, delay, &area->t_opaque_lsa_self);
delay += top->min_ls_interval;
}
"Schedule Type-11 Opaque-LSA origination in %d ms later.",
delay);
top->t_opaque_lsa_self = NULL;
- thread_add_timer_msec(master, ospf_opaque_type11_lsa_originate,
- top, delay, &top->t_opaque_lsa_self);
+ event_add_timer_msec(master, ospf_opaque_type11_lsa_originate,
+ top, delay, &top->t_opaque_lsa_self);
delay += top->min_ls_interval;
}
*delay0 = delay;
}
-static void ospf_opaque_type9_lsa_originate(struct thread *t)
+static void ospf_opaque_type9_lsa_originate(struct event *t)
{
struct ospf_interface *oi;
- oi = THREAD_ARG(t);
+ oi = EVENT_ARG(t);
oi->t_opaque_lsa_self = NULL;
if (IS_DEBUG_OSPF_EVENT)
opaque_lsa_originate_callback(ospf_opaque_type9_funclist, oi);
}
-static void ospf_opaque_type10_lsa_originate(struct thread *t)
+static void ospf_opaque_type10_lsa_originate(struct event *t)
{
struct ospf_area *area;
- area = THREAD_ARG(t);
+ area = EVENT_ARG(t);
area->t_opaque_lsa_self = NULL;
if (IS_DEBUG_OSPF_EVENT)
opaque_lsa_originate_callback(ospf_opaque_type10_funclist, area);
}
-static void ospf_opaque_type11_lsa_originate(struct thread *t)
+static void ospf_opaque_type11_lsa_originate(struct event *t)
{
struct ospf *top;
- top = THREAD_ARG(t);
+ top = EVENT_ARG(t);
top->t_opaque_lsa_self = NULL;
if (IS_DEBUG_OSPF_EVENT)
* triggered by external interventions (vty session, signaling, etc).
*------------------------------------------------------------------------*/
-#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) thread_add_timer_msec (master, (F), (L), (V), &(T))
+#define OSPF_OPAQUE_TIMER_ON(T, F, L, V) \
+ event_add_timer_msec(master, (F), (L), (V), &(T))
static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi,
struct ospf_area *area, uint8_t lsa_type,
uint8_t opaque_type);
-static void ospf_opaque_type9_lsa_reoriginate_timer(struct thread *t);
-static void ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t);
-static void ospf_opaque_type11_lsa_reoriginate_timer(struct thread *t);
-static void ospf_opaque_lsa_refresh_timer(struct thread *t);
+static void ospf_opaque_type9_lsa_reoriginate_timer(struct event *t);
+static void ospf_opaque_type10_lsa_reoriginate_timer(struct event *t);
+static void ospf_opaque_type11_lsa_reoriginate_timer(struct event *t);
+static void ospf_opaque_lsa_refresh_timer(struct event *t);
void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
uint8_t lsa_type, uint8_t opaque_type)
struct ospf_lsa *lsa;
struct opaque_info_per_type *oipt;
- void (*func)(struct thread * t) = NULL;
+ void (*func)(struct event * t) = NULL;
int delay;
switch (lsa_type) {
return &lsa;
}
-static void ospf_opaque_type9_lsa_reoriginate_timer(struct thread *t)
+static void ospf_opaque_type9_lsa_reoriginate_timer(struct event *t)
{
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
struct ospf *top;
struct ospf_interface *oi;
- oipt = THREAD_ARG(t);
+ oipt = EVENT_ARG(t);
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL) {
(*functab->lsa_originator)(oi);
}
-static void ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t)
+static void ospf_opaque_type10_lsa_reoriginate_timer(struct event *t)
{
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
struct ospf_interface *oi;
int n;
- oipt = THREAD_ARG(t);
+ oipt = EVENT_ARG(t);
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL) {
(*functab->lsa_originator)(area);
}
-static void ospf_opaque_type11_lsa_reoriginate_timer(struct thread *t)
+static void ospf_opaque_type11_lsa_reoriginate_timer(struct event *t)
{
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
struct ospf *top;
- oipt = THREAD_ARG(t);
+ oipt = EVENT_ARG(t);
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL) {
return;
}
-static void ospf_opaque_lsa_refresh_timer(struct thread *t)
+static void ospf_opaque_lsa_refresh_timer(struct event *t)
{
struct opaque_info_per_id *oipi;
struct ospf_opaque_functab *functab;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)");
- oipi = THREAD_ARG(t);
+ oipi = EVENT_ARG(t);
if ((lsa = oipi->lsa) != NULL)
if ((functab = oipi->opqctl_type->functab) != NULL)
#include <zebra.h>
#include "monotime.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
}
-static void ospf_ls_req_timer(struct thread *thread)
+static void ospf_ls_req_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_ls_req = NULL;
/* Send Link State Request. */
void ospf_ls_req_event(struct ospf_neighbor *nbr)
{
- THREAD_OFF(nbr->t_ls_req);
- thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req);
+ EVENT_OFF(nbr->t_ls_req);
+ event_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req);
}
/* Cyclic timer function. Fist registered in ospf_nbr_new () in
ospf_neighbor.c */
-void ospf_ls_upd_timer(struct thread *thread)
+void ospf_ls_upd_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_ls_upd = NULL;
/* Send Link State Update. */
OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
}
-void ospf_ls_ack_timer(struct thread *thread)
+void ospf_ls_ack_timer(struct event *thread)
{
struct ospf_interface *oi;
- oi = THREAD_ARG(thread);
+ oi = EVENT_ARG(thread);
oi->t_ls_ack = NULL;
/* Send Link State Acknowledgment. */
}
#endif /* WANT_OSPF_WRITE_FRAGMENT */
-static void ospf_write(struct thread *thread)
+static void ospf_write(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
struct ospf_interface *oi;
struct ospf_packet *op;
struct sockaddr_in sa_dst;
/* If packets still remain in queue, call write thread. */
if (!list_isempty(ospf->oi_write_q))
- thread_add_write(master, ospf_write, ospf, ospf->fd,
- &ospf->t_write);
+ event_add_write(master, ospf_write, ospf, ospf->fd,
+ &ospf->t_write);
}
/* OSPF Hello message read -- RFC2328 Section 10.5. */
}
/* Starting point of packet process function. */
-void ospf_read(struct thread *thread)
+void ospf_read(struct event *thread)
{
struct ospf *ospf;
int32_t count = 0;
enum ospf_read_return_enum ret;
/* first of all get interface pointer. */
- ospf = THREAD_ARG(thread);
+ ospf = EVENT_ARG(thread);
/* prepare for next packet. */
- thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
+ event_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
while (count < ospf->write_oi_count) {
count++;
ospf_hello_send_sub(oi, nbr_nbma->addr.s_addr);
}
-void ospf_poll_timer(struct thread *thread)
+void ospf_poll_timer(struct event *thread)
{
struct ospf_nbr_nbma *nbr_nbma;
- nbr_nbma = THREAD_ARG(thread);
+ nbr_nbma = EVENT_ARG(thread);
nbr_nbma->t_poll = NULL;
if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
}
-void ospf_hello_reply_timer(struct thread *thread)
+void ospf_hello_reply_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_hello_reply = NULL;
if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
ospf_packet_add(oi, op);
/* Call ospf_write() right away to send ospf packets to neighbors */
if (send_lsupd_now) {
- struct thread os_packet_thd;
+ struct event os_packet_thd;
os_packet_thd.arg = (void *)oi->ospf;
if (oi->on_write_q == 0) {
* is actually turned off.
*/
if (list_isempty(oi->ospf->oi_write_q))
- THREAD_OFF(oi->ospf->t_write);
+ EVENT_OFF(oi->ospf->t_write);
} else {
/* Hook thread to write packet. */
OSPF_ISM_WRITE_ON(oi->ospf);
}
}
-static void ospf_ls_upd_send_queue_event(struct thread *thread)
+static void ospf_ls_upd_send_queue_event(struct event *thread)
{
- struct ospf_interface *oi = THREAD_ARG(thread);
+ struct ospf_interface *oi = EVENT_ARG(thread);
struct route_node *rn;
struct route_node *rnext;
struct list *update;
"%s: update lists not cleared, %d nodes to try again, raising new event",
__func__, again);
oi->t_ls_upd_event = NULL;
- thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
- &oi->t_ls_upd_event);
+ event_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ &oi->t_ls_upd_event);
}
if (IS_DEBUG_OSPF_EVENT)
rn->p.u.prefix4, 1);
}
} else
- thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
- &oi->t_ls_upd_event);
+ event_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ &oi->t_ls_upd_event);
}
static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
OSPF_ISM_WRITE_ON(oi->ospf);
}
-static void ospf_ls_ack_send_event(struct thread *thread)
+static void ospf_ls_ack_send_event(struct event *thread)
{
- struct ospf_interface *oi = THREAD_ARG(thread);
+ struct ospf_interface *oi = EVENT_ARG(thread);
oi->t_ls_ack_direct = NULL;
listnode_add(oi->ls_ack_direct.ls_ack, ospf_lsa_lock(lsa));
- thread_add_event(master, ospf_ls_ack_send_event, oi, 0,
- &oi->t_ls_ack_direct);
+ event_add_event(master, ospf_ls_ack_send_event, oi, 0,
+ &oi->t_ls_ack_direct);
}
/* Send Link State Acknowledgment delayed. */
extern void ospf_fifo_flush(struct ospf_fifo *);
extern void ospf_fifo_free(struct ospf_fifo *);
-extern void ospf_read(struct thread *thread);
+extern void ospf_read(struct event *thread);
extern void ospf_hello_send(struct ospf_interface *);
extern void ospf_db_desc_send(struct ospf_neighbor *);
extern void ospf_db_desc_resend(struct ospf_neighbor *);
extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *);
extern void ospf_ls_req_event(struct ospf_neighbor *);
-extern void ospf_ls_upd_timer(struct thread *thread);
-extern void ospf_ls_ack_timer(struct thread *thread);
-extern void ospf_poll_timer(struct thread *thread);
-extern void ospf_hello_reply_timer(struct thread *thread);
+extern void ospf_ls_upd_timer(struct event *thread);
+extern void ospf_ls_ack_timer(struct event *thread);
+extern void ospf_poll_timer(struct event *thread);
+extern void ospf_hello_reply_timer(struct event *thread);
extern const struct message ospf_packet_type_str[];
extern const size_t ospf_packet_type_str_max;
#include "vty.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "mpls.h"
}
/* Register OSPF2-MIB. */
-static int ospf_snmp_init(struct thread_master *tm)
+static int ospf_snmp_init(struct event_loop *tm)
{
ospf_snmp_iflist = list_new();
ospf_snmp_vl_table = route_table_init();
#include <zebra.h>
#include "monotime.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "hash.h"
#include "linklist.h"
}
/* Worker for SPF calculation scheduler. */
-static void ospf_spf_calculate_schedule_worker(struct thread *thread)
+static void ospf_spf_calculate_schedule_worker(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
struct route_table *new_table, *new_rtrs;
struct route_table *all_rtrs = NULL;
struct timeval start_time, spf_start_time;
zlog_debug("SPF: calculation timer delay = %ld msec", delay);
ospf->t_spf_calc = NULL;
- thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf,
- delay, &ospf->t_spf_calc);
+ event_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf,
+ delay, &ospf->t_spf_calc);
}
/* Restart OSPF SPF algorithm*/
#include "sockunion.h" /* for inet_aton() */
#include "stream.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "zclient.h"
#include "sbuf.h"
*
* @return 1 on success
*/
-static void sr_start_label_manager(struct thread *start)
+static void sr_start_label_manager(struct event *start)
{
struct ospf *ospf;
- ospf = THREAD_ARG(start);
+ ospf = EVENT_ARG(start);
/* re-attempt to start SR & Label Manager connection */
ospf_sr_start(ospf);
if (!ospf_zebra_label_manager_ready())
if (ospf_zebra_label_manager_connect() < 0) {
/* Re-attempt to connect to Label Manager in 1 sec. */
- thread_add_timer(master, sr_start_label_manager, ospf,
- 1, &OspfSR.t_start_lm);
+ event_add_timer(master, sr_start_label_manager, ospf, 1,
+ &OspfSR.t_start_lm);
osr_debug(" |- Failed to start the Label Manager");
return -1;
}
osr_debug("SR (%s): Stop Segment Routing", __func__);
/* Disable any re-attempt to connect to Label Manager */
- THREAD_OFF(OspfSR.t_start_lm);
+ EVENT_OFF(OspfSR.t_start_lm);
/* Release SRGB if active */
sr_global_block_delete();
/* Stop Segment Routing */
ospf_sr_stop();
- /* Clear SR Node Table */
- if (OspfSR.neighbors)
- hash_free(OspfSR.neighbors);
-
+ hash_clean_and_free(&OspfSR.neighbors, (void *)sr_node_del);
}
/*
uint8_t msd;
/* Thread timer to start Label Manager */
- struct thread *t_start_lm;
+ struct event *t_start_lm;
};
/* Structure aggregating all received SR info from LSAs by node */
#include "vty.h"
#include "stream.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "network.h"
#include "printfrr.h"
#include "monotime.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "table.h"
#include "vty.h"
for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
SET_FLAG(area->stub_router_state,
OSPF_AREA_WAS_START_STUB_ROUTED);
- THREAD_OFF(area->t_stub_router);
+ EVENT_OFF(area->t_stub_router);
/* Don't trample on admin stub routed */
if (!CHECK_FLAG(area->stub_router_state,
.actual_grace_period);
vty_out(vty,
" Remaining GraceTime:%ld(in seconds).\n",
- thread_timer_remain_second(
+ event_timer_remain_second(
nbr->gr_helper_info
- .t_grace_timer));
+ .t_grace_timer));
vty_out(vty,
" Graceful Restart reason: %s.\n\n",
ospf_restart_reason2str(
.actual_grace_period);
json_object_int_add(
json_neigh, "remainGracetime",
- thread_timer_remain_second(
+ event_timer_remain_second(
nbr->gr_helper_info
- .t_grace_timer));
+ .t_grace_timer));
json_object_string_add(
json_neigh, "restartReason",
ospf_restart_reason2str(
else
ospf->maxage_delay = value;
- THREAD_OFF(ospf->t_maxage);
+ EVENT_OFF(ospf->t_maxage);
OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover,
ospf->maxage_delay);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "network.h"
#include "prefix.h"
static struct zclient *zclient_sync;
/* For registering threads. */
-extern struct thread_master *master;
+extern struct event_loop *master;
/* Router-id update message from zebra. */
static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
* Function to originate or flush default after applying
* route-map on all ei.
*/
-static void ospf_external_lsa_default_routemap_timer(struct thread *thread)
+static void ospf_external_lsa_default_routemap_timer(struct event *thread)
{
struct list *ext_list;
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
struct prefix_ipv4 p;
int type;
int ret = 0;
/*
* Check if default needs to be flushed too.
*/
- thread_add_event(master, ospf_external_lsa_default_routemap_timer, ospf,
- 0, &ospf->t_default_routemap_timer);
+ event_add_event(master, ospf_external_lsa_default_routemap_timer, ospf,
+ 0, &ospf->t_default_routemap_timer);
}
/* Update NHLFE for Prefix SID */
* there are any other external info which can still trigger
* default route origination else flush it.
*/
- thread_add_event(master,
- ospf_external_lsa_default_routemap_timer, ospf,
- 0, &ospf->t_default_routemap_timer);
+ event_add_event(master,
+ ospf_external_lsa_default_routemap_timer, ospf,
+ 0, &ospf->t_default_routemap_timer);
}
return true;
}
/* distribute-list update timer. */
-static void ospf_distribute_list_update_timer(struct thread *thread)
+static void ospf_distribute_list_update_timer(struct event *thread)
{
struct route_node *rn;
struct external_info *ei;
struct route_table *rt;
struct ospf_lsa *lsa;
int type, default_refresh = 0;
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
if (ospf == NULL)
return;
return;
/* Set timer. If timer is already started, this call does nothing. */
- thread_add_timer_msec(master, ospf_distribute_list_update_timer, ospf,
- ospf->min_ls_interval,
- &ospf->t_distribute_update);
+ event_add_timer_msec(master, ospf_distribute_list_update_timer, ospf,
+ ospf->min_ls_interval, &ospf->t_distribute_update);
}
/* If access-list is updated, apply some check. */
[ZEBRA_CLIENT_CLOSE_NOTIFY] = ospf_zebra_client_close_notify,
};
-void ospf_zebra_init(struct thread_master *master, unsigned short instance)
+void ospf_zebra_init(struct event_loop *master, unsigned short instance)
{
/* Allocate zebra structure. */
zclient = zclient_new(master, &zclient_options_default, ospf_handlers,
const char *, const char *);
extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
const char *, const char *);
-extern void ospf_zebra_init(struct thread_master *, unsigned short);
+extern void ospf_zebra_init(struct event_loop *m, unsigned short instance);
extern void ospf_zebra_vrf_register(struct ospf *ospf);
extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
bool ospf_external_default_routemap_apply_walk(
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "linklist.h"
new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
new->maxage_lsa = route_table_init();
new->t_maxage_walker = NULL;
- thread_add_timer(master, ospf_lsa_maxage_walker, new,
- OSPF_LSA_MAXAGE_CHECK_INTERVAL, &new->t_maxage_walker);
+ event_add_timer(master, ospf_lsa_maxage_walker, new,
+ OSPF_LSA_MAXAGE_CHECK_INTERVAL, &new->t_maxage_walker);
/* Max paths initialization */
new->max_multipath = MULTIPATH_NUM;
new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
new->lsa_refresh_timer = OSPF_LS_REFRESH_TIME;
new->t_lsa_refresher = NULL;
- thread_add_timer(master, ospf_lsa_refresh_walker, new,
- new->lsa_refresh_interval, &new->t_lsa_refresher);
+ event_add_timer(master, ospf_lsa_refresh_walker, new,
+ new->lsa_refresh_interval, &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1);
return new;
}
- thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
+ event_add_read(master, ospf_read, new, new->fd, &new->t_read);
new->oi_running = 1;
ospf_router_id_update(new);
static void ospf_deferred_shutdown_finish(struct ospf *ospf)
{
ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
- THREAD_OFF(ospf->t_deferred_shutdown);
+ EVENT_OFF(ospf->t_deferred_shutdown);
ospf_finish_final(ospf);
}
/* Timer thread for G-R */
-static void ospf_deferred_shutdown_timer(struct thread *t)
+static void ospf_deferred_shutdown_timer(struct event *t)
{
- struct ospf *ospf = THREAD_ARG(t);
+ struct ospf *ospf = EVENT_ARG(t);
ospf_deferred_shutdown_finish(ospf);
}
/* Clear static neighbors */
for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
if ((nbr_nbma = rn->info)) {
- THREAD_OFF(nbr_nbma->t_poll);
+ EVENT_OFF(nbr_nbma->t_poll);
if (nbr_nbma->nbr) {
nbr_nbma->nbr->nbr_nbma = NULL;
}
/* Cancel all timers. */
- THREAD_OFF(ospf->t_read);
- THREAD_OFF(ospf->t_write);
- THREAD_OFF(ospf->t_spf_calc);
- THREAD_OFF(ospf->t_ase_calc);
- THREAD_OFF(ospf->t_maxage);
- THREAD_OFF(ospf->t_maxage_walker);
- THREAD_OFF(ospf->t_abr_task);
- THREAD_OFF(ospf->t_abr_fr);
- THREAD_OFF(ospf->t_asbr_check);
- THREAD_OFF(ospf->t_asbr_nssa_redist_update);
- THREAD_OFF(ospf->t_distribute_update);
- THREAD_OFF(ospf->t_lsa_refresher);
- THREAD_OFF(ospf->t_opaque_lsa_self);
- THREAD_OFF(ospf->t_sr_update);
- THREAD_OFF(ospf->t_default_routemap_timer);
- THREAD_OFF(ospf->t_external_aggr);
- THREAD_OFF(ospf->gr_info.t_grace_period);
+ EVENT_OFF(ospf->t_read);
+ EVENT_OFF(ospf->t_write);
+ EVENT_OFF(ospf->t_spf_calc);
+ EVENT_OFF(ospf->t_ase_calc);
+ EVENT_OFF(ospf->t_maxage);
+ EVENT_OFF(ospf->t_maxage_walker);
+ EVENT_OFF(ospf->t_abr_task);
+ EVENT_OFF(ospf->t_abr_fr);
+ EVENT_OFF(ospf->t_asbr_check);
+ EVENT_OFF(ospf->t_asbr_nssa_redist_update);
+ EVENT_OFF(ospf->t_distribute_update);
+ EVENT_OFF(ospf->t_lsa_refresher);
+ EVENT_OFF(ospf->t_opaque_lsa_self);
+ EVENT_OFF(ospf->t_sr_update);
+ EVENT_OFF(ospf->t_default_routemap_timer);
+ EVENT_OFF(ospf->t_external_aggr);
+ EVENT_OFF(ospf->gr_info.t_grace_period);
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
free(IMPORT_NAME(area));
/* Cancel timer. */
- THREAD_OFF(area->t_stub_router);
- THREAD_OFF(area->t_opaque_lsa_self);
+ EVENT_OFF(area->t_stub_router);
+ EVENT_OFF(area->t_opaque_lsa_self);
if (OSPF_IS_AREA_BACKBONE(area))
area->ospf->backbone = NULL;
}
/* remove update event */
- THREAD_OFF(oi->t_ls_upd_event);
+ EVENT_OFF(oi->t_ls_upd_event);
}
void ospf_if_update(struct ospf *ospf, struct interface *ifp)
- (monotime(NULL) - ospf->lsa_refresher_started);
if (time_left > interval) {
- THREAD_OFF(ospf->t_lsa_refresher);
- thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
- interval, &ospf->t_lsa_refresher);
+ EVENT_OFF(ospf->t_lsa_refresher);
+ event_add_timer(master, ospf_lsa_refresh_walker, ospf, interval,
+ &ospf->t_lsa_refresher);
}
ospf->lsa_refresh_interval = interval;
- (monotime(NULL) - ospf->lsa_refresher_started);
if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) {
- THREAD_OFF(ospf->t_lsa_refresher);
+ EVENT_OFF(ospf->t_lsa_refresher);
ospf->t_lsa_refresher = NULL;
- thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
- OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
- &ospf->t_lsa_refresher);
+ event_add_timer(master, ospf_lsa_refresh_walker, ospf,
+ OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
+ &ospf->t_lsa_refresher);
}
ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
static void ospf_nbr_nbma_down(struct ospf_nbr_nbma *nbr_nbma)
{
- THREAD_OFF(nbr_nbma->t_poll);
+ EVENT_OFF(nbr_nbma->t_poll);
if (nbr_nbma->nbr) {
nbr_nbma->nbr->nbr_nbma = NULL;
if (nbr_nbma->v_poll != interval) {
nbr_nbma->v_poll = interval;
if (nbr_nbma->oi && ospf_if_is_up(nbr_nbma->oi)) {
- THREAD_OFF(nbr_nbma->t_poll);
+ EVENT_OFF(nbr_nbma->t_poll);
OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer,
nbr_nbma->v_poll);
}
return 1;
}
-void ospf_master_init(struct thread_master *master)
+void ospf_master_init(struct event_loop *master)
{
memset(&ospf_master, 0, sizeof(ospf_master));
ret = ospf_sock_init(ospf);
if (ret < 0 || ospf->fd <= 0)
return 0;
- thread_add_read(master, ospf_read, ospf, ospf->fd,
- &ospf->t_read);
+ event_add_read(master, ospf_read, ospf, ospf->fd,
+ &ospf->t_read);
ospf->oi_running = 1;
ospf_router_id_update(ospf);
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__,
old_vrf_id);
- THREAD_OFF(ospf->t_read);
+ EVENT_OFF(ospf->t_read);
close(ospf->fd);
ospf->fd = -1;
}
struct list *ospf;
/* OSPF thread master. */
- struct thread_master *master;
+ struct event_loop *master;
/* Various OSPF global configuration. */
uint8_t options;
bool prepare_in_progress;
bool finishing_restart;
uint32_t grace_period;
- struct thread *t_grace_period;
+ struct event *t_grace_period;
};
/* OSPF instance structure. */
int redistribute; /* Num of redistributed protocols. */
/* Threads. */
- struct thread *t_abr_task; /* ABR task timer. */
- struct thread *t_abr_fr; /* ABR FR timer. */
- struct thread *t_asbr_check; /* ASBR check timer. */
- struct thread *t_asbr_nssa_redist_update; /* ASBR NSSA redistribution
+ struct event *t_abr_task; /* ABR task timer. */
+ struct event *t_abr_fr; /* ABR FR timer. */
+ struct event *t_asbr_check; /* ASBR check timer. */
+ struct event *t_asbr_nssa_redist_update; /* ASBR NSSA redistribution
update timer. */
- struct thread *t_distribute_update; /* Distirbute list update timer. */
- struct thread *t_spf_calc; /* SPF calculation timer. */
- struct thread *t_ase_calc; /* ASE calculation timer. */
- struct thread
- *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
- struct thread *t_sr_update; /* Segment Routing update timer */
+ struct event *t_distribute_update; /* Distirbute list update timer. */
+ struct event *t_spf_calc; /* SPF calculation timer. */
+ struct event *t_ase_calc; /* ASE calculation timer. */
+ struct event *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
+ struct event *t_sr_update; /* Segment Routing update timer */
unsigned int maxage_delay; /* Delay on Maxage remover timer, sec */
- struct thread *t_maxage; /* MaxAge LSA remover timer. */
- struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */
+ struct event *t_maxage; /* MaxAge LSA remover timer. */
+ struct event *t_maxage_walker; /* MaxAge LSA checking timer. */
- struct thread
+ struct event
*t_deferred_shutdown; /* deferred/stub-router shutdown timer*/
- struct thread *t_write;
+ struct event *t_write;
#define OSPF_WRITE_INTERFACE_COUNT_DEFAULT 20
- struct thread *t_default_routemap_timer;
+ struct event *t_default_routemap_timer;
int write_oi_count; /* Num of packets sent per thread invocation */
- struct thread *t_read;
+ struct event *t_read;
int fd;
struct stream *ibuf;
struct list *oi_write_q;
struct list *qs[OSPF_LSA_REFRESHER_SLOTS];
} lsa_refresh_queue;
- struct thread *t_lsa_refresher;
+ struct event *t_lsa_refresher;
time_t lsa_refresher_started;
#define OSPF_LSA_REFRESH_INTERVAL_DEFAULT 10
uint16_t lsa_refresh_interval;
/* delay timer to process external routes
* with summary address.
*/
- struct thread *t_external_aggr;
+ struct event *t_external_aggr;
/* delay interval in seconds */
uint16_t aggr_delay_interval;
struct p_spaces_head *p_spaces;
/* Threads. */
- struct thread *t_stub_router; /* Stub-router timer */
- struct thread *t_opaque_lsa_self; /* Type-10 Opaque-LSAs origin. */
+ struct event *t_stub_router; /* Stub-router timer */
+ struct event *t_opaque_lsa_self; /* Type-10 Opaque-LSAs origin. */
/* Statistics field. */
uint32_t spf_calculation; /* SPF Calculation Count. */
uint32_t v_poll;
/* Poll timer thread. */
- struct thread *t_poll;
+ struct event *t_poll;
/* State change. */
uint32_t state_change;
#define LSA_OPTIONS_NSSA_GET(area) \
(((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0)
-#define OSPF_TIMER_ON(T,F,V) thread_add_timer (master,(F),ospf,(V),&(T))
-#define OSPF_AREA_TIMER_ON(T,F,V) thread_add_timer (master, (F), area, (V), &(T))
-#define OSPF_POLL_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr_nbma, (V), &(T))
+#define OSPF_TIMER_ON(T, F, V) event_add_timer(master, (F), ospf, (V), &(T))
+#define OSPF_AREA_TIMER_ON(T, F, V) \
+ event_add_timer(master, (F), area, (V), &(T))
+#define OSPF_POLL_TIMER_ON(T, F, V) \
+ event_add_timer(master, (F), nbr_nbma, (V), &(T))
/* Extern variables. */
extern struct ospf_master *om;
extern unsigned short ospf_instance;
extern const int ospf_redistributed_proto_max;
extern struct zclient *zclient;
-extern struct thread_master *master;
+extern struct event_loop *master;
extern int ospf_zlog;
extern struct zebra_privs_t ospfd_privs;
extern void ospf_route_map_init(void);
-extern void ospf_master_init(struct thread_master *master);
+extern void ospf_master_init(struct event_loop *master);
extern void ospf_vrf_init(void);
extern void ospf_vrf_terminate(void);
extern void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf);
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "log.h"
#include "memory.h"
struct option longopts[] = {{0}};
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
static struct frr_daemon_info pathd_di;
/* Module Functions */
static int pcep_module_finish(void);
-static int pcep_module_late_init(struct thread_master *tm);
+static int pcep_module_late_init(struct event_loop *tm);
static int pcep_module_init(void);
/* ------------ Path Helper Functions ------------ */
* run before config load, so the CLI commands don't try to touch things that
* aren't set up yet...
*/
-static int pcep_module_config_pre(struct thread_master *tm)
+static int pcep_module_config_pre(struct event_loop *tm)
{
assert(pcep_g->fpt == NULL);
assert(pcep_g->master == NULL);
return 0;
}
-static int pcep_module_late_init(struct thread_master *tm)
+static int pcep_module_late_init(struct event_loop *tm)
{
hook_register(pathd_candidate_created, pathd_candidate_created_handler);
hook_register(pathd_candidate_updated, pathd_candidate_updated_handler);
struct pcep_glob {
struct debug dbg;
- struct thread_master *master;
+ struct event_loop *master;
struct frr_pthread *fpt;
uint8_t num_pce_opts_cli;
struct pce_opts_cli *pce_opts_cli[MAX_PCE];
#include "pathd/path_pcep.h"
#include "pathd/path_pcep_config.h"
#include "pathd/path_pcep_debug.h"
-#include "thread.h"
+#include "frrevent.h"
#define MAX_XPATH 256
#define MAX_FLOAT_LEN 22
/* Internal Functions Called From Main Thread */
static int pcep_ctrl_halt_cb(struct frr_pthread *fpt, void **res);
-static void pcep_refine_path_event_cb(struct thread *thread);
+static void pcep_refine_path_event_cb(struct event *thread);
/* Internal Functions Called From Controller Thread */
-static void pcep_thread_finish_event_handler(struct thread *thread);
+static void pcep_thread_finish_event_handler(struct event *thread);
/* Controller Thread Timer Handler */
static int schedule_thread_timer(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_timer_type timer_type,
enum pcep_ctrl_timeout_type timeout_type,
uint32_t delay, void *payload,
- struct thread **thread);
+ struct event **thread);
static int schedule_thread_timer_with_cb(
struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_timer_type timer_type,
enum pcep_ctrl_timeout_type timeout_type, uint32_t delay, void *payload,
- struct thread **thread, pcep_ctrl_thread_callback timer_cb);
-static void pcep_thread_timer_handler(struct thread *thread);
+ struct event **thread, pcep_ctrl_thread_callback timer_cb);
+static void pcep_thread_timer_handler(struct event *thread);
/* Controller Thread Socket read/write Handler */
static int schedule_thread_socket(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_socket_type type, bool is_read,
- void *payload, int fd, struct thread **thread,
+ void *payload, int fd, struct event **thread,
pcep_ctrl_thread_callback cb);
/* Controller Thread Event Handler */
enum pcep_ctrl_event_type type,
uint32_t sub_type, void *payload,
pcep_ctrl_thread_callback event_cb);
-static void pcep_thread_event_handler(struct thread *thread);
+static void pcep_thread_event_handler(struct event *thread);
static int pcep_thread_event_update_pcc_options(struct ctrl_state *ctrl_state,
struct pcc_opts *opts);
static int pcep_thread_event_update_pce_options(struct ctrl_state *ctrl_state,
/* Main Thread Event Handler */
static int send_to_main(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_main_event_type type, void *payload);
-static void pcep_main_event_handler(struct thread *thread);
+static void pcep_main_event_handler(struct event *thread);
/* Helper functions */
static void set_ctrl_state(struct frr_pthread *fpt,
/* ------------ API Functions Called from Main Thread ------------ */
-int pcep_ctrl_initialize(struct thread_master *main_thread,
+int pcep_ctrl_initialize(struct event_loop *main_thread,
struct frr_pthread **fpt,
pcep_main_event_handler_t event_handler)
{
int pcep_ctrl_halt_cb(struct frr_pthread *fpt, void **res)
{
- thread_add_event(fpt->master, pcep_thread_finish_event_handler,
- (void *)fpt, 0, NULL);
+ event_add_event(fpt->master, pcep_thread_finish_event_handler,
+ (void *)fpt, 0, NULL);
pthread_join(fpt->thread, res);
return 0;
}
-void pcep_refine_path_event_cb(struct thread *thread)
+void pcep_refine_path_event_cb(struct event *thread)
{
- struct pcep_refine_path_event_data *data = THREAD_ARG(thread);
+ struct pcep_refine_path_event_data *data = EVENT_ARG(thread);
assert(data != NULL);
struct ctrl_state *ctrl_state = data->ctrl_state;
struct path *path = data->path;
void pcep_thread_schedule_sync_best_pce(struct ctrl_state *ctrl_state,
int pcc_id, int delay,
- struct thread **thread)
+ struct event **thread)
{
schedule_thread_timer(ctrl_state, pcc_id, TM_CALCULATE_BEST_PCE,
TO_UNDEFINED, delay, NULL, thread);
}
-void pcep_thread_cancel_timer(struct thread **thread)
+void pcep_thread_cancel_timer(struct event **thread)
{
if (thread == NULL || *thread == NULL) {
return;
}
- struct pcep_ctrl_timer_data *data = THREAD_ARG(*thread);
+ struct pcep_ctrl_timer_data *data = EVENT_ARG(*thread);
PCEP_DEBUG("Timer %s / %s canceled", timer_type_name(data->timer_type),
timeout_type_name(data->timeout_type));
if (data != NULL) {
}
if ((*thread)->master->owner == pthread_self()) {
- thread_cancel(thread);
+ event_cancel(thread);
} else {
- thread_cancel_async((*thread)->master, thread, NULL);
+ event_cancel_async((*thread)->master, thread, NULL);
}
}
void pcep_thread_schedule_reconnect(struct ctrl_state *ctrl_state, int pcc_id,
- int retry_count, struct thread **thread)
+ int retry_count, struct event **thread)
{
uint32_t delay = backoff_delay(MAX_RECONNECT_DELAY, 1, retry_count);
PCEP_DEBUG("Schedule RECONNECT_PCC for %us (retry %u)", delay,
void pcep_thread_schedule_timeout(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_timeout_type timeout_type,
uint32_t delay, void *param,
- struct thread **thread)
+ struct event **thread)
{
assert(timeout_type > TO_UNDEFINED);
assert(timeout_type < TO_MAX);
void pcep_thread_schedule_pceplib_timer(struct ctrl_state *ctrl_state,
int delay, void *payload,
- struct thread **thread,
+ struct event **thread,
pcep_ctrl_thread_callback timer_cb)
{
PCEP_DEBUG("Schedule PCEPLIB_TIMER for %us", delay);
void pcep_thread_schedule_session_timeout(struct ctrl_state *ctrl_state,
int pcc_id, int delay,
- struct thread **thread)
+ struct event **thread)
{
PCEP_DEBUG("Schedule session_timeout interval for %us", delay);
schedule_thread_timer(ctrl_state, pcc_id, TM_SESSION_TIMEOUT_PCC,
data->continue_lsp_update_handler = cb;
data->payload = payload;
- thread_add_event(ctrl_state->main, pcep_refine_path_event_cb,
- (void *)data, 0, NULL);
+ event_add_event(ctrl_state->main, pcep_refine_path_event_cb,
+ (void *)data, 0, NULL);
return 0;
}
/* ------------ Internal Functions Called From Controller Thread ------------ */
-void pcep_thread_finish_event_handler(struct thread *thread)
+void pcep_thread_finish_event_handler(struct event *thread)
{
int i;
- struct frr_pthread *fpt = THREAD_ARG(thread);
+ struct frr_pthread *fpt = EVENT_ARG(thread);
struct ctrl_state *ctrl_state = fpt->data;
assert(ctrl_state != NULL);
enum pcep_ctrl_timer_type timer_type,
enum pcep_ctrl_timeout_type timeout_type,
uint32_t delay, void *payload,
- struct thread **thread,
+ struct event **thread,
pcep_ctrl_thread_callback timer_cb)
{
assert(thread != NULL);
data->pcc_id = pcc_id;
data->payload = payload;
- thread_add_timer(ctrl_state->self, timer_cb, (void *)data, delay,
- thread);
+ event_add_timer(ctrl_state->self, timer_cb, (void *)data, delay,
+ thread);
return 0;
}
int schedule_thread_timer(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_timer_type timer_type,
enum pcep_ctrl_timeout_type timeout_type,
- uint32_t delay, void *payload, struct thread **thread)
+ uint32_t delay, void *payload, struct event **thread)
{
return schedule_thread_timer_with_cb(ctrl_state, pcc_id, timer_type,
timeout_type, delay, payload,
thread, pcep_thread_timer_handler);
}
-void pcep_thread_timer_handler(struct thread *thread)
+void pcep_thread_timer_handler(struct event *thread)
{
/* data unpacking */
- struct pcep_ctrl_timer_data *data = THREAD_ARG(thread);
+ struct pcep_ctrl_timer_data *data = EVENT_ARG(thread);
assert(data != NULL);
struct ctrl_state *ctrl_state = data->ctrl_state;
assert(ctrl_state != NULL);
}
}
-void pcep_thread_pcep_event(struct thread *thread)
+void pcep_thread_pcep_event(struct event *thread)
{
- struct pcep_ctrl_event_data *data = THREAD_ARG(thread);
+ struct pcep_ctrl_event_data *data = EVENT_ARG(thread);
assert(data != NULL);
struct ctrl_state *ctrl_state = data->ctrl_state;
pcep_event *event = data->payload;
int schedule_thread_socket(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_socket_type type, bool is_read,
- void *payload, int fd, struct thread **thread,
+ void *payload, int fd, struct event **thread,
pcep_ctrl_thread_callback socket_cb)
{
assert(thread != NULL);
data->payload = payload;
if (is_read) {
- thread_add_read(ctrl_state->self, socket_cb, (void *)data, fd,
- thread);
+ event_add_read(ctrl_state->self, socket_cb, (void *)data, fd,
+ thread);
} else {
- thread_add_write(ctrl_state->self, socket_cb, (void *)data, fd,
- thread);
+ event_add_write(ctrl_state->self, socket_cb, (void *)data, fd,
+ thread);
}
return 0;
struct ctrl_state *ctrl_state = ((struct frr_pthread *)fpt)->data;
return schedule_thread_socket(ctrl_state, 0, SOCK_PCEPLIB, false,
- payload, fd, (struct thread **)thread,
+ payload, fd, (struct event **)thread,
socket_cb);
}
struct ctrl_state *ctrl_state = ((struct frr_pthread *)fpt)->data;
return schedule_thread_socket(ctrl_state, 0, SOCK_PCEPLIB, true,
- payload, fd, (struct thread **)thread,
+ payload, fd, (struct event **)thread,
socket_cb);
}
data->pcc_id = pcc_id;
data->payload = payload;
- thread_add_event(ctrl_state->self, event_cb, (void *)data, 0, NULL);
+ event_add_event(ctrl_state->self, event_cb, (void *)data, 0, NULL);
return 0;
}
-void pcep_thread_event_handler(struct thread *thread)
+void pcep_thread_event_handler(struct event *thread)
{
/* data unpacking */
- struct pcep_ctrl_event_data *data = THREAD_ARG(thread);
+ struct pcep_ctrl_event_data *data = EVENT_ARG(thread);
assert(data != NULL);
struct ctrl_state *ctrl_state = data->ctrl_state;
assert(ctrl_state != NULL);
data->pcc_id = pcc_id;
data->payload = payload;
- thread_add_event(ctrl_state->main, pcep_main_event_handler,
- (void *)data, 0, NULL);
+ event_add_event(ctrl_state->main, pcep_main_event_handler, (void *)data,
+ 0, NULL);
return 0;
}
-void pcep_main_event_handler(struct thread *thread)
+void pcep_main_event_handler(struct event *thread)
{
/* data unpacking */
- struct pcep_main_event_data *data = THREAD_ARG(thread);
+ struct pcep_main_event_data *data = EVENT_ARG(thread);
assert(data != NULL);
pcep_main_event_handler_t handler = data->handler;
enum pcep_main_event_type type = data->type;
};
struct ctrl_state {
- struct thread_master *main;
- struct thread_master *self;
+ struct event_loop *main;
+ struct event_loop *self;
pcep_main_event_handler_t main_event_handler;
struct pcc_opts *pcc_opts;
int pcc_count;
void *payload;
};
-typedef void (*pcep_ctrl_thread_callback)(struct thread *);
+typedef void (*pcep_ctrl_thread_callback)(struct event *);
/* PCC connection information, populated in a thread-safe
* manner with pcep_ctrl_get_pcc_info() */
};
/* Functions called from the main thread */
-int pcep_ctrl_initialize(struct thread_master *main_thread,
+int pcep_ctrl_initialize(struct event_loop *main_thread,
struct frr_pthread **fpt,
pcep_main_event_handler_t event_handler);
int pcep_ctrl_finalize(struct frr_pthread **fpt);
struct path *path);
void pcep_thread_initiate_path(struct ctrl_state *ctrl_state, int pcc_id,
struct path *path);
-void pcep_thread_cancel_timer(struct thread **thread);
+void pcep_thread_cancel_timer(struct event **thread);
void pcep_thread_schedule_reconnect(struct ctrl_state *ctrl_state, int pcc_id,
- int retry_count, struct thread **thread);
+ int retry_count, struct event **thread);
void pcep_thread_schedule_timeout(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_timeout_type type,
uint32_t delay, void *param,
- struct thread **thread);
+ struct event **thread);
void pcep_thread_schedule_session_timeout(struct ctrl_state *ctrl_state,
int pcc_id, int delay,
- struct thread **thread);
+ struct event **thread);
void pcep_thread_remove_candidate_path_segments(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state);
void pcep_thread_schedule_sync_best_pce(struct ctrl_state *ctrl_state,
int pcc_id, int delay,
- struct thread **thread);
+ struct event **thread);
void pcep_thread_schedule_pceplib_timer(struct ctrl_state *ctrl_state,
int delay, void *payload,
- struct thread **thread,
+ struct event **thread,
pcep_ctrl_thread_callback cb);
int pcep_thread_socket_read(void *fpt, void **thread, int fd, void *payload,
pcep_ctrl_thread_callback cb);
int pcep_thread_send_ctrl_event(void *fpt, void *payload,
pcep_ctrl_thread_callback cb);
-void pcep_thread_pcep_event(struct thread *thread);
+void pcep_thread_pcep_event(struct event *thread);
int pcep_thread_pcc_count(struct ctrl_state *ctrl_state);
/* Called by the PCC to refine a path in the main thread */
int pcep_thread_refine_path(struct ctrl_state *ctrl_state, int pcc_id,
void *payload);
static int pcep_lib_pceplib_socket_write_cb(void *fpt, void **thread, int fd,
void *payload);
-static void pcep_lib_socket_read_ready(struct thread *thread);
-static void pcep_lib_socket_write_ready(struct thread *thread);
+static void pcep_lib_socket_read_ready(struct event *thread);
+static void pcep_lib_socket_write_ready(struct event *thread);
/* pceplib pcep_event callbacks */
static void pcep_lib_pceplib_event_cb(void *fpt, pcep_event *event);
/* Callbacks called by path_pcep_controller when a socket is ready to read/write
*/
-void pcep_lib_socket_write_ready(struct thread *thread)
+void pcep_lib_socket_write_ready(struct event *thread)
{
- struct pcep_ctrl_socket_data *data = THREAD_ARG(thread);
+ struct pcep_ctrl_socket_data *data = EVENT_ARG(thread);
assert(data != NULL);
pceplib_external_socket_write(data->fd, data->payload);
XFREE(MTYPE_PCEP, data);
}
-void pcep_lib_socket_read_ready(struct thread *thread)
+void pcep_lib_socket_read_ready(struct event *thread)
{
- struct pcep_ctrl_socket_data *data = THREAD_ARG(thread);
+ struct pcep_ctrl_socket_data *data = EVENT_ARG(thread);
assert(data != NULL);
pceplib_external_socket_read(data->fd, data->payload);
}
if (pcc_state->t_reconnect != NULL) {
- thread_cancel(&pcc_state->t_reconnect);
+ event_cancel(&pcc_state->t_reconnect);
pcc_state->t_reconnect = NULL;
}
if (pcc_state->t_update_best != NULL) {
- thread_cancel(&pcc_state->t_update_best);
+ event_cancel(&pcc_state->t_update_best);
pcc_state->t_update_best = NULL;
}
if (pcc_state->t_session_timeout != NULL) {
- thread_cancel(&pcc_state->t_session_timeout);
+ event_cancel(&pcc_state->t_session_timeout);
pcc_state->t_session_timeout = NULL;
}
assert(pcc_state->sess == NULL);
if (pcc_state->t_reconnect != NULL) {
- thread_cancel(&pcc_state->t_reconnect);
+ event_cancel(&pcc_state->t_reconnect);
pcc_state->t_reconnect = NULL;
}
// In case some best pce alternative were waiting to activate
if (pcc_state->t_update_best != NULL) {
- thread_cancel(&pcc_state->t_update_best);
+ event_cancel(&pcc_state->t_update_best);
pcc_state->t_update_best = NULL;
}
struct req_entry {
RB_ENTRY(req_entry) entry;
- struct thread *t_retry;
+ struct event *t_retry;
int retry_count;
bool was_sent;
struct path *path;
pcep_session *sess;
uint32_t retry_count;
bool synchronized;
- struct thread *t_reconnect;
- struct thread *t_update_best;
- struct thread *t_session_timeout;
+ struct event *t_reconnect;
+ struct event *t_update_best;
+ struct event *t_session_timeout;
uint32_t next_reqid;
uint32_t next_plspid;
struct plspid_map_head plspid_map;
static uint32_t path_ted_start_importing_igp(const char *daemon_str);
static uint32_t path_ted_stop_importing_igp(void);
static enum zclient_send_status path_ted_link_state_sync(void);
-static void path_ted_timer_handler_sync(struct thread *thread);
-static void path_ted_timer_handler_refresh(struct thread *thread);
+static void path_ted_timer_handler_sync(struct event *thread);
+static void path_ted_timer_handler_refresh(struct event *thread);
static int path_ted_cli_debug_config_write(struct vty *vty);
static int path_ted_cli_debug_set_all(uint32_t flags, bool set);
* path_path_ted public API function implementations
*/
-void path_ted_init(struct thread_master *master)
+void path_ted_init(struct event_loop *master)
{
ted_state_g.main = master;
ted_state_g.link_state_delay_interval = TIMER_RETRY_DELAY;
PATH_TED_DEBUG("%s: PATHD-TED: Opaque asked for TED sync ",
__func__);
}
- thread_add_timer(ted_state_g.main, path_ted_timer_handler_sync,
- &ted_state_g, ted_state_g.link_state_delay_interval,
- &ted_state_g.t_link_state_sync);
+ event_add_timer(ted_state_g.main, path_ted_timer_handler_sync,
+ &ted_state_g, ted_state_g.link_state_delay_interval,
+ &ted_state_g.t_link_state_sync);
return status;
}
*
* @return status
*/
-void path_ted_timer_handler_sync(struct thread *thread)
+void path_ted_timer_handler_sync(struct event *thread)
{
/* data unpacking */
- struct ted_state *data = THREAD_ARG(thread);
+ struct ted_state *data = EVENT_ARG(thread);
assert(data != NULL);
/* Retry the sync */
int status = 0;
path_ted_timer_refresh_cancel();
- thread_add_timer(ted_state_g.main, path_ted_timer_handler_refresh,
- &ted_state_g,
- ted_state_g.segment_list_refresh_interval,
- &ted_state_g.t_segment_list_refresh);
+ event_add_timer(ted_state_g.main, path_ted_timer_handler_refresh,
+ &ted_state_g, ted_state_g.segment_list_refresh_interval,
+ &ted_state_g.t_segment_list_refresh);
return status;
}
*
* @return status
*/
-void path_ted_timer_handler_refresh(struct thread *thread)
+void path_ted_timer_handler_refresh(struct event *thread)
{
if (!path_ted_is_initialized())
return;
PATH_TED_DEBUG("%s: PATHD-TED: Refresh sid from current TED", __func__);
/* data unpacking */
- struct ted_state *data = THREAD_ARG(thread);
+ struct ted_state *data = EVENT_ARG(thread);
assert(data != NULL);
void path_ted_timer_sync_cancel(void)
{
if (ted_state_g.t_link_state_sync != NULL) {
- thread_cancel(&ted_state_g.t_link_state_sync);
+ event_cancel(&ted_state_g.t_link_state_sync);
ted_state_g.t_link_state_sync = NULL;
}
}
void path_ted_timer_refresh_cancel(void)
{
if (ted_state_g.t_segment_list_refresh != NULL) {
- thread_cancel(&ted_state_g.t_segment_list_refresh);
+ event_cancel(&ted_state_g.t_segment_list_refresh);
ted_state_g.t_segment_list_refresh = NULL;
}
}
IMPORT_OSPFv3
};
struct ted_state {
- struct thread_master *main;
+ struct event_loop *main;
/* Status of TED: enable or disable */
bool enabled;
/* From which igp is going to receive data */
/* The TED itself as in link_state.h */
struct ls_ted *ted;
/* Timer for ted sync */
- struct thread *t_link_state_sync;
+ struct event *t_link_state_sync;
/* Timer for refresh sid in segment list */
- struct thread *t_segment_list_refresh;
+ struct event *t_segment_list_refresh;
/* delay interval in seconds */
uint32_t link_state_delay_interval;
/* delay interval refresh in seconds */
/* TED management functions */
bool path_ted_is_initialized(void);
-void path_ted_init(struct thread_master *master);
+void path_ted_init(struct event_loop *master);
uint32_t path_ted_teardown(void);
void path_ted_timer_sync_cancel(void);
void path_ted_timer_refresh_cancel(void);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "lib_errors.h"
#include "if.h"
*
* @param master The master thread
*/
-void path_zebra_init(struct thread_master *master)
+void path_zebra_init(struct event_loop *master)
{
struct zclient_options options = zclient_options_default;
options.synchronous = true;
void path_zebra_delete_sr_policy(struct srte_policy *policy);
int path_zebra_request_label(mpls_label_t label);
void path_zebra_release_label(mpls_label_t label);
-void path_zebra_init(struct thread_master *master);
+void path_zebra_init(struct event_loop *master);
void path_zebra_stop(void);
#endif /* _FRR_PATH_MPLS_H_ */
static void trigger_pathd_candidate_created(struct srte_candidate *candidate);
-static void trigger_pathd_candidate_created_timer(struct thread *thread);
+static void trigger_pathd_candidate_created_timer(struct event *thread);
static void trigger_pathd_candidate_updated(struct srte_candidate *candidate);
-static void trigger_pathd_candidate_updated_timer(struct thread *thread);
+static void trigger_pathd_candidate_updated_timer(struct event *thread);
static void trigger_pathd_candidate_removed(struct srte_candidate *candidate);
static const char *
srte_candidate_metric_name(enum srte_candidate_metric_type type);
from changing the candidate by hand with the console */
if (candidate->hook_timer != NULL)
return;
- thread_add_timer(master, trigger_pathd_candidate_created_timer,
- (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
+ event_add_timer(master, trigger_pathd_candidate_created_timer,
+ (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
}
-void trigger_pathd_candidate_created_timer(struct thread *thread)
+void trigger_pathd_candidate_created_timer(struct event *thread)
{
- struct srte_candidate *candidate = THREAD_ARG(thread);
+ struct srte_candidate *candidate = EVENT_ARG(thread);
candidate->hook_timer = NULL;
hook_call(pathd_candidate_created, candidate);
}
from changing the candidate by hand with the console */
if (candidate->hook_timer != NULL)
return;
- thread_add_timer(master, trigger_pathd_candidate_updated_timer,
- (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
+ event_add_timer(master, trigger_pathd_candidate_updated_timer,
+ (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
}
-void trigger_pathd_candidate_updated_timer(struct thread *thread)
+void trigger_pathd_candidate_updated_timer(struct event *thread)
{
- struct srte_candidate *candidate = THREAD_ARG(thread);
+ struct srte_candidate *candidate = EVENT_ARG(thread);
candidate->hook_timer = NULL;
hook_call(pathd_candidate_updated, candidate);
}
/* The hook needs to be call synchronously, otherwise the candidate
path will be already deleted when the handler is called */
if (candidate->hook_timer != NULL) {
- thread_cancel(&candidate->hook_timer);
+ event_cancel(&candidate->hook_timer);
candidate->hook_timer = NULL;
}
hook_call(pathd_candidate_removed, candidate);
uint32_t affinity_filters[MAX_AFFINITY_FILTER_TYPE];
/* Hooks delaying timer */
- struct thread *hook_timer;
+ struct event *hook_timer;
};
RB_HEAD(srte_candidate_head, srte_candidate);
extern struct zebra_privs_t pathd_privs;
/* master thread, defined in path_main.c */
-extern struct thread_master *master;
+extern struct event_loop *master;
/* pathd.c */
struct srte_segment_list *srte_segment_list_add(const char *name);
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "linklist.h"
#include "if.h"
struct option longopts[] = { { 0 } };
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/* SIGHUP handler. */
static void sighup(void)
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "prefix.h"
#include "table.h"
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "network.h"
#include "prefix.h"
char mapname[100];
};
-extern struct thread_master *master;
+extern struct event_loop *master;
extern void pbr_zebra_init(void);
"Source address\n")
{
char xpath[XPATH_MAXLEN];
+ struct ipaddr group_addr = {0};
+
+ (void)str2ipaddr(group_str, &group_addr);
+
+ if (!IN6_IS_ADDR_MULTICAST(&group_addr)) {
+ vty_out(vty, "Invalid Multicast Address\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
if (source_str) {
if (IPV6_ADDR_SAME(&source, &in6addr_any)) {
#include "lib/jhash.h"
#include "lib/prefix.h"
#include "lib/checksum.h"
-#include "lib/thread.h"
+#include "lib/frrevent.h"
#include "termtable.h"
#include "pimd/pim6_mld.h"
DEFINE_MTYPE_STATIC(PIMD, GM_GRP_PENDING, "MLD group query state");
DEFINE_MTYPE_STATIC(PIMD, GM_GSQ_PENDING, "MLD group/source query aggregate");
-static void gm_t_query(struct thread *t);
+static void gm_t_query(struct event *t);
static void gm_trigger_specific(struct gm_sg *sg);
static void gm_sg_timer_start(struct gm_if *gm_ifp, struct gm_sg *sg,
struct timeval expire_wait);
static void gm_sg_free(struct gm_sg *sg)
{
/* t_sg_expiry is handled before this is reached */
- THREAD_OFF(sg->t_sg_query);
+ EVENT_OFF(sg->t_sg_query);
gm_packet_sg_subs_fini(sg->subs_negative);
gm_packet_sg_subs_fini(sg->subs_positive);
XFREE(MTYPE_GM_SG, sg);
gm_expiry_calc(&timers);
gm_sg_timer_start(gm_ifp, sg, timers.expire_wait);
- THREAD_OFF(sg->t_sg_query);
+ EVENT_OFF(sg->t_sg_query);
sg->n_query = gm_ifp->cur_lmqc;
sg->query_sbit = false;
gm_trigger_specific(sg);
* another path.
*/
if (has_expired)
- THREAD_OFF(sg->t_sg_expire);
+ EVENT_OFF(sg->t_sg_expire);
assertf((!sg->t_sg_expire &&
!gm_packet_sg_subs_count(sg->subs_positive) &&
{
if (sg->t_sg_expire && PIM_DEBUG_GM_TRACE)
zlog_debug(log_sg(sg, "alive, cancelling expiry timer"));
- THREAD_OFF(sg->t_sg_expire);
+ EVENT_OFF(sg->t_sg_expire);
sg->query_sbit = true;
}
* its own path too and won't hit this. This is really only triggered when a
* host straight up disappears.
*/
-static void gm_t_expire(struct thread *t)
+static void gm_t_expire(struct event *t)
{
- struct gm_if *gm_ifp = THREAD_ARG(t);
+ struct gm_if *gm_ifp = EVENT_ARG(t);
struct gm_packet_state *pkt;
zlog_info(log_ifp("general expiry timer"));
log_ifp("next general expiry in %" PRId64 "ms"),
remain_ms / 1000);
- thread_add_timer_tv(router->master, gm_t_expire, gm_ifp,
- &remain, &gm_ifp->t_expire);
+ event_add_timer_tv(router->master, gm_t_expire, gm_ifp,
+ &remain, &gm_ifp->t_expire);
return;
}
gm_ifp->n_pending--;
if (!gm_ifp->n_pending)
- THREAD_OFF(gm_ifp->t_expire);
+ EVENT_OFF(gm_ifp->t_expire);
}
/* people might be messing with their configs or something */
zlog_debug(
log_ifp("starting general timer @ 0: %pTVMu"),
&pend->expiry);
- thread_add_timer_tv(router->master, gm_t_expire, gm_ifp,
- &timers->expire_wait, &gm_ifp->t_expire);
+ event_add_timer_tv(router->master, gm_t_expire, gm_ifp,
+ &timers->expire_wait, &gm_ifp->t_expire);
} else if (PIM_DEBUG_GM_TRACE)
zlog_debug(log_ifp("appending general timer @ %u: %pTVMu"),
gm_ifp->n_pending, &pend->expiry);
}
-static void gm_t_sg_expire(struct thread *t)
+static void gm_t_sg_expire(struct event *t)
{
- struct gm_sg *sg = THREAD_ARG(t);
+ struct gm_sg *sg = EVENT_ARG(t);
struct gm_if *gm_ifp = sg->iface;
struct gm_packet_sg *item;
if (sg->t_sg_expire) {
struct timeval remain;
- remain = thread_timer_remain(sg->t_sg_expire);
+ remain = event_timer_remain(sg->t_sg_expire);
if (timercmp(&remain, &expire_wait, <=))
return;
- THREAD_OFF(sg->t_sg_expire);
+ EVENT_OFF(sg->t_sg_expire);
}
- thread_add_timer_tv(router->master, gm_t_sg_expire, sg, &expire_wait,
- &sg->t_sg_expire);
+ event_add_timer_tv(router->master, gm_t_sg_expire, sg, &expire_wait,
+ &sg->t_sg_expire);
}
static void gm_handle_q_groupsrc(struct gm_if *gm_ifp,
}
}
-static void gm_t_grp_expire(struct thread *t)
+static void gm_t_grp_expire(struct event *t)
{
/* if we're here, that means when we received the group-specific query
* there was one or more active S,G for this group. For *,G the timer
* receive a report, so that work is left to gm_t_sg_expire and we
* shouldn't worry about it here.
*/
- struct gm_grp_pending *pend = THREAD_ARG(t);
+ struct gm_grp_pending *pend = EVENT_ARG(t);
struct gm_if *gm_ifp = pend->iface;
struct gm_sg *sg, *sg_start, sg_ref = {};
* parallel. But if we received nothing for the *,G query,
* the S,G query is kinda irrelevant.
*/
- THREAD_OFF(sg->t_sg_expire);
+ EVENT_OFF(sg->t_sg_expire);
frr_each_safe (gm_packet_sg_subs, sg->subs_positive, item)
/* this will also drop the EXCLUDE S,G lists */
if (pend) {
struct timeval remain;
- remain = thread_timer_remain(pend->t_expire);
+ remain = event_timer_remain(pend->t_expire);
if (timercmp(&remain, &timers->expire_wait, <=))
return;
- THREAD_OFF(pend->t_expire);
+ EVENT_OFF(pend->t_expire);
} else {
pend = XCALLOC(MTYPE_GM_GRP_PENDING, sizeof(*pend));
pend->grp = grp;
}
monotime(&pend->query);
- thread_add_timer_tv(router->master, gm_t_grp_expire, pend,
- &timers->expire_wait, &pend->t_expire);
+ event_add_timer_tv(router->master, gm_t_grp_expire, pend,
+ &timers->expire_wait, &pend->t_expire);
if (PIM_DEBUG_GM_TRACE)
zlog_debug(log_ifp("*,%pPAs S,G timer started: %pTHD"), &grp,
{
struct pim_interface *pim_ifp = gm_ifp->ifp->info;
- THREAD_OFF(gm_ifp->t_query);
+ EVENT_OFF(gm_ifp->t_query);
if (pim_addr_is_any(pim_ifp->ll_lowest))
return;
gm_ifp->n_startup = gm_ifp->cur_qrv;
- thread_execute(router->master, gm_t_query, gm_ifp, 0);
+ event_execute(router->master, gm_t_query, gm_ifp, 0);
}
-static void gm_t_other_querier(struct thread *t)
+static void gm_t_other_querier(struct event *t)
{
- struct gm_if *gm_ifp = THREAD_ARG(t);
+ struct gm_if *gm_ifp = EVENT_ARG(t);
struct pim_interface *pim_ifp = gm_ifp->ifp->info;
zlog_info(log_ifp("other querier timer expired"));
gm_ifp->querier = pim_ifp->ll_lowest;
gm_ifp->n_startup = gm_ifp->cur_qrv;
- thread_execute(router->master, gm_t_query, gm_ifp, 0);
+ event_execute(router->master, gm_t_query, gm_ifp, 0);
}
static void gm_handle_query(struct gm_if *gm_ifp,
if (IPV6_ADDR_CMP(&pkt_src->sin6_addr, &pim_ifp->ll_lowest) < 0) {
unsigned int other_ms;
- THREAD_OFF(gm_ifp->t_query);
- THREAD_OFF(gm_ifp->t_other_querier);
+ EVENT_OFF(gm_ifp->t_query);
+ EVENT_OFF(gm_ifp->t_other_querier);
other_ms = timers.qrv * timers.qqic_ms + timers.max_resp_ms / 2;
- thread_add_timer_msec(router->master, gm_t_other_querier,
- gm_ifp, other_ms,
- &gm_ifp->t_other_querier);
+ event_add_timer_msec(router->master, gm_t_other_querier, gm_ifp,
+ other_ms, &gm_ifp->t_other_querier);
}
if (len == sizeof(struct mld_v1_pkt)) {
return false;
}
-static void gm_t_recv(struct thread *t)
+static void gm_t_recv(struct event *t)
{
- struct pim_instance *pim = THREAD_ARG(t);
+ struct pim_instance *pim = EVENT_ARG(t);
union {
char buf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(256) /* hop options */ +
ssize_t nread;
size_t pktlen;
- thread_add_read(router->master, gm_t_recv, pim, pim->gm_socket,
- &pim->t_gm_recv);
+ event_add_read(router->master, gm_t_recv, pim, pim->gm_socket,
+ &pim->t_gm_recv);
iov->iov_base = rxbuf;
iov->iov_len = sizeof(rxbuf);
}
}
-static void gm_t_query(struct thread *t)
+static void gm_t_query(struct event *t)
{
- struct gm_if *gm_ifp = THREAD_ARG(t);
+ struct gm_if *gm_ifp = EVENT_ARG(t);
unsigned int timer_ms = gm_ifp->cur_query_intv;
if (gm_ifp->n_startup) {
gm_ifp->n_startup--;
}
- thread_add_timer_msec(router->master, gm_t_query, gm_ifp, timer_ms,
- &gm_ifp->t_query);
+ event_add_timer_msec(router->master, gm_t_query, gm_ifp, timer_ms,
+ &gm_ifp->t_query);
gm_send_query(gm_ifp, PIMADDR_ANY, NULL, 0, false);
}
-static void gm_t_sg_query(struct thread *t)
+static void gm_t_sg_query(struct event *t)
{
- struct gm_sg *sg = THREAD_ARG(t);
+ struct gm_sg *sg = EVENT_ARG(t);
gm_trigger_specific(sg);
}
XFREE(MTYPE_GM_GSQ_PENDING, pend_gsq);
}
-static void gm_t_gsq_pend(struct thread *t)
+static void gm_t_gsq_pend(struct event *t)
{
- struct gm_gsq_pending *pend_gsq = THREAD_ARG(t);
+ struct gm_gsq_pending *pend_gsq = EVENT_ARG(t);
gm_send_specific(pend_gsq);
}
sg->n_query--;
if (sg->n_query)
- thread_add_timer_msec(router->master, gm_t_sg_query, sg,
- gm_ifp->cur_query_intv_trig,
- &sg->t_sg_query);
+ event_add_timer_msec(router->master, gm_t_sg_query, sg,
+ gm_ifp->cur_query_intv_trig,
+ &sg->t_sg_query);
if (!IPV6_ADDR_SAME(&gm_ifp->querier, &pim_ifp->ll_lowest))
return;
pend_gsq->iface = gm_ifp;
gm_gsq_pends_add(gm_ifp->gsq_pends, pend_gsq);
- thread_add_timer_tv(router->master, gm_t_gsq_pend, pend_gsq,
- &gm_ifp->cfg_timing_fuzz,
- &pend_gsq->t_send);
+ event_add_timer_tv(router->master, gm_t_gsq_pend, pend_gsq,
+ &gm_ifp->cfg_timing_fuzz, &pend_gsq->t_send);
}
assert(pend_gsq->n_src < array_size(pend_gsq->srcs));
pend_gsq->n_src++;
if (pend_gsq->n_src == array_size(pend_gsq->srcs)) {
- THREAD_OFF(pend_gsq->t_send);
+ EVENT_OFF(pend_gsq->t_send);
gm_send_specific(pend_gsq);
pend_gsq = NULL;
}
vrf->name);
}
- thread_add_read(router->master, gm_t_recv, pim, pim->gm_socket,
- &pim->t_gm_recv);
+ event_add_read(router->master, gm_t_recv, pim, pim->gm_socket,
+ &pim->t_gm_recv);
}
static void gm_vrf_socket_decref(struct pim_instance *pim)
if (--pim->gm_socket_if_count)
return;
- THREAD_OFF(pim->t_gm_recv);
+ EVENT_OFF(pim->t_gm_recv);
close(pim->gm_socket);
pim->gm_socket = -1;
}
gm_packet_drop(pkt, false);
while ((pend_grp = gm_grp_pends_pop(gm_ifp->grp_pends))) {
- THREAD_OFF(pend_grp->t_expire);
+ EVENT_OFF(pend_grp->t_expire);
XFREE(MTYPE_GM_GRP_PENDING, pend_grp);
}
while ((pend_gsq = gm_gsq_pends_pop(gm_ifp->gsq_pends))) {
- THREAD_OFF(pend_gsq->t_send);
+ EVENT_OFF(pend_gsq->t_send);
XFREE(MTYPE_GM_GSQ_PENDING, pend_gsq);
}
while ((sg = gm_sgs_pop(gm_ifp->sgs))) {
- THREAD_OFF(sg->t_sg_expire);
+ EVENT_OFF(sg->t_sg_expire);
assertf(!gm_packet_sg_subs_count(sg->subs_negative), "%pSG",
&sg->sgaddr);
assertf(!gm_packet_sg_subs_count(sg->subs_positive), "%pSG",
if (PIM_DEBUG_GM_EVENTS)
zlog_debug(log_ifp("MLD stop"));
- THREAD_OFF(gm_ifp->t_query);
- THREAD_OFF(gm_ifp->t_other_querier);
- THREAD_OFF(gm_ifp->t_expire);
+ EVENT_OFF(gm_ifp->t_query);
+ EVENT_OFF(gm_ifp->t_other_querier);
+ EVENT_OFF(gm_ifp->t_expire);
frr_with_privs (&pimd_privs) {
struct ipv6_mreq mreq;
gm_ifp->cur_ll_lowest = pim_ifp->ll_lowest;
if (was_querier)
gm_ifp->querier = pim_ifp->ll_lowest;
- THREAD_OFF(gm_ifp->t_query);
+ EVENT_OFF(gm_ifp->t_query);
if (pim_addr_is_any(gm_ifp->cur_ll_lowest)) {
if (was_querier)
return;
gm_ifp->n_startup = gm_ifp->cur_qrv;
- thread_execute(router->master, gm_t_query, gm_ifp, 0);
+ event_execute(router->master, gm_t_query, gm_ifp, 0);
}
void gm_ifp_update(struct interface *ifp)
#include "typesafe.h"
#include "pim_addr.h"
-struct thread;
+struct event;
struct pim_instance;
struct gm_packet_sg;
struct gm_if;
* (implies we haven't received any report yet, since it's cancelled
* by that)
*/
- struct thread *t_sg_expire;
+ struct event *t_sg_expire;
/* last-member-left triggered queries (group/group-source specific)
*
* this timer will be running even if we aren't the elected querier,
* in case the election result changes midway through.
*/
- struct thread *t_sg_query;
+ struct event *t_sg_query;
/* we must keep sending (QRV) queries even if we get a positive
* response, to make sure other routers are updated. query_sbit
pim_addr grp;
struct timeval query;
- struct thread *t_expire;
+ struct event *t_expire;
};
/* guaranteed MTU for IPv6 is 1280 bytes. IPv6 header is 40 bytes, MLDv2
struct gm_gsq_pends_item itm;
struct gm_if *iface;
- struct thread *t_send;
+ struct event *t_send;
pim_addr grp;
bool s_bit;
struct gm_if {
struct interface *ifp;
struct pim_instance *pim;
- struct thread *t_query, *t_other_querier, *t_expire;
+ struct event *t_query, *t_other_querier, *t_expire;
bool stopping;
return pim_assert_do(ch, metric);
}
-static void on_assert_timer(struct thread *t)
+static void on_assert_timer(struct event *t)
{
struct pim_ifchannel *ch;
struct interface *ifp;
- ch = THREAD_ARG(t);
+ ch = EVENT_ARG(t);
ifp = ch->interface;
__func__, ch->sg_str, ch->interface->name);
}
}
- THREAD_OFF(ch->t_ifassert_timer);
+ EVENT_OFF(ch->t_ifassert_timer);
}
static void pim_assert_timer_set(struct pim_ifchannel *ch, int interval)
__func__, ch->sg_str, interval, ch->interface->name);
}
- thread_add_timer(router->master, on_assert_timer, ch, interval,
- &ch->t_ifassert_timer);
+ event_add_timer(router->master, on_assert_timer, ch, interval,
+ &ch->t_ifassert_timer);
}
static void pim_assert_timer_reset(struct pim_ifchannel *ch)
static void pim_bsm_rpinfo_free(struct bsm_rpinfo *bsrp_info)
{
- THREAD_OFF(bsrp_info->g2rp_timer);
+ EVENT_OFF(bsrp_info->g2rp_timer);
XFREE(MTYPE_PIM_BSRP_INFO, bsrp_info);
}
return bsgrp;
}
-static void pim_on_bs_timer(struct thread *t)
+static void pim_on_bs_timer(struct event *t)
{
struct route_node *rn;
struct bsm_scope *scope;
struct bsgrp_node *bsgrp_node;
struct bsm_rpinfo *bsrp;
- scope = THREAD_ARG(t);
- THREAD_OFF(scope->bs_timer);
+ scope = EVENT_ARG(t);
+ EVENT_OFF(scope->bs_timer);
if (PIM_DEBUG_BSM)
zlog_debug("%s: Bootstrap Timer expired for scope: %d",
if (PIM_DEBUG_BSM)
zlog_debug("%s : BS timer being stopped of sz: %d", __func__,
scope->sz_id);
- THREAD_OFF(scope->bs_timer);
+ EVENT_OFF(scope->bs_timer);
}
static void pim_bs_timer_start(struct bsm_scope *scope, int bs_timeout)
zlog_debug("%s : Invalid scope(NULL).", __func__);
return;
}
- THREAD_OFF(scope->bs_timer);
+ EVENT_OFF(scope->bs_timer);
if (PIM_DEBUG_BSM)
zlog_debug(
"%s : starting bs timer for scope %d with timeout %d secs",
__func__, scope->sz_id, bs_timeout);
- thread_add_timer(router->master, pim_on_bs_timer, scope, bs_timeout,
- &scope->bs_timer);
+ event_add_timer(router->master, pim_on_bs_timer, scope, bs_timeout,
+ &scope->bs_timer);
}
static inline void pim_bs_timer_restart(struct bsm_scope *scope, int bs_timeout)
return true;
}
-static void pim_on_g2rp_timer(struct thread *t)
+static void pim_on_g2rp_timer(struct event *t)
{
struct bsm_rpinfo *bsrp;
struct bsm_rpinfo *bsrp_node;
uint16_t elapse;
pim_addr bsrp_addr;
- bsrp = THREAD_ARG(t);
- THREAD_OFF(bsrp->g2rp_timer);
+ bsrp = EVENT_ARG(t);
+ EVENT_OFF(bsrp->g2rp_timer);
bsgrp_node = bsrp->bsgrp_node;
/* elapse time is the hold time of expired node */
zlog_debug("%s : Invalid brsp(NULL).", __func__);
return;
}
- THREAD_OFF(bsrp->g2rp_timer);
+ EVENT_OFF(bsrp->g2rp_timer);
if (PIM_DEBUG_BSM)
zlog_debug(
"%s : starting g2rp timer for grp: %pFX - rp: %pPAs with timeout %d secs(Actual Hold time : %d secs)",
__func__, &bsrp->bsgrp_node->group, &bsrp->rp_address,
hold_time, bsrp->rp_holdtime);
- thread_add_timer(router->master, pim_on_g2rp_timer, bsrp, hold_time,
- &bsrp->g2rp_timer);
+ event_add_timer(router->master, pim_on_g2rp_timer, bsrp, hold_time,
+ &bsrp->g2rp_timer);
}
static inline void pim_g2rp_timer_restart(struct bsm_rpinfo *bsrp,
__func__, &bsrp->bsgrp_node->group,
&bsrp->rp_address);
- THREAD_OFF(bsrp->g2rp_timer);
+ EVENT_OFF(bsrp->g2rp_timer);
}
static bool is_hold_time_zero(void *data)
struct bsm_frags_head bsm_frags[1];
struct route_table *bsrp_table; /* group2rp mapping rcvd from BSR */
- struct thread *bs_timer; /* Boot strap timer */
+ struct event *bs_timer; /* Boot strap timer */
};
/* BSM packet (= fragment) - this is stored as list in bsm_frags inside scope
uint16_t rp_holdtime; /* RP holdtime - g2rp timer value */
pim_addr rp_address; /* RP Address */
struct bsgrp_node *bsgrp_node; /* Back ptr to bsgrp_node */
- struct thread *g2rp_timer; /* Run only for elected RP node */
+ struct event *g2rp_timer; /* Run only for elected RP node */
};
extern int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *a,
zlog_warn("%s: ifindex=%d < 1 on interface %s", __func__,
ifp->ifindex, ifp->name);
return -2;
+ } else if ((ifp->ifindex == 0) &&
+ ((strncmp(ifp->name, "pimreg", 6)) &&
+ (strncmp(ifp->name, "pim6reg", 7)))) {
+ zlog_warn("%s: ifindex=%d == 0 on interface %s", __func__,
+ ifp->ifindex, ifp->name);
+ return -2;
}
ifaddr = pim_ifp->primary_address;
struct gm_if *mld;
int pim_sock_fd; /* PIM socket file descriptor */
- struct thread *t_pim_sock_read; /* thread for reading PIM socket */
+ struct event *t_pim_sock_read; /* thread for reading PIM socket */
int64_t pim_sock_creation; /* timestamp of PIM socket creation */
- struct thread *t_pim_hello_timer;
+ struct event *t_pim_hello_timer;
int pim_hello_period;
int pim_default_holdtime;
int pim_triggered_hello_delay;
#include <zebra.h>
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "if.h"
#include "vrf.h"
ch->upstream = NULL;
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_OFF(ch->t_ifassert_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_prune_pending_timer);
+ EVENT_OFF(ch->t_ifassert_timer);
if (ch->parent) {
listnode_delete(ch->parent->sources, ch);
*/
void reset_ifassert_state(struct pim_ifchannel *ch)
{
- THREAD_OFF(ch->t_ifassert_timer);
+ EVENT_OFF(ch->t_ifassert_timer);
pim_ifassert_winner_set(ch, PIM_IFASSERT_NOINFO, PIMADDR_ANY,
router->infinite_assert_metric);
delete_on_noinfo(ch);
}
-static void on_ifjoin_expiry_timer(struct thread *t)
+static void on_ifjoin_expiry_timer(struct event *t)
{
struct pim_ifchannel *ch;
- ch = THREAD_ARG(t);
+ ch = EVENT_ARG(t);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug("%s: ifchannel %s expiry timer", __func__,
/* ch may have been deleted */
}
-static void on_ifjoin_prune_pending_timer(struct thread *t)
+static void on_ifjoin_prune_pending_timer(struct event *t)
{
struct pim_ifchannel *ch;
int send_prune_echo; /* boolean */
struct interface *ifp;
struct pim_interface *pim_ifp;
- ch = THREAD_ARG(t);
+ ch = EVENT_ARG(t);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug("%s: IFCHANNEL%pSG %s Prune Pending Timer Popped",
previously received join message with holdtime=0xFFFF.
*/
if (ch->t_ifjoin_expiry_timer) {
- unsigned long remain = thread_timer_remain_second(
+ unsigned long remain = event_timer_remain_second(
ch->t_ifjoin_expiry_timer);
if (remain > holdtime) {
/*
return;
}
}
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
break;
case PIM_IFJOIN_PRUNE:
if (source_flags & PIM_ENCODE_RPT_BIT) {
pim_ifchannel_ifjoin_switch(__func__, ch,
PIM_IFJOIN_NOINFO);
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
delete_on_noinfo(ch);
return;
} else
* maximum of its current value and the HoldTime from the
* triggering Join/Prune message.
*/
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ EVENT_OFF(ch->t_ifjoin_prune_pending_timer);
/* Check if SGRpt join Received */
if ((source_flags & PIM_ENCODE_RPT_BIT) &&
* I transitions to the NoInfo state.The ET and PPT are
* cancelled.
*/
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
pim_ifchannel_ifjoin_switch(__func__, ch,
PIM_IFJOIN_NOINFO);
return;
pim_ifchannel_ifjoin_handler(ch, pim_ifp);
if (ch->t_ifjoin_expiry_timer) {
- unsigned long remain = thread_timer_remain_second(
+ unsigned long remain = event_timer_remain_second(
ch->t_ifjoin_expiry_timer);
if (remain > holdtime)
return;
}
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
break;
case PIM_IFJOIN_PRUNE_TMP:
}
if (holdtime != 0xFFFF) {
- thread_add_timer(router->master, on_ifjoin_expiry_timer, ch,
- holdtime, &ch->t_ifjoin_expiry_timer);
+ event_add_timer(router->master, on_ifjoin_expiry_timer, ch,
+ holdtime, &ch->t_ifjoin_expiry_timer);
}
}
be taken not to use "ch" afterwards since it would be
deleted. */
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer_msec(
- router->master, on_ifjoin_prune_pending_timer,
- ch, jp_override_interval_msec,
- &ch->t_ifjoin_prune_pending_timer);
- thread_add_timer(router->master, on_ifjoin_expiry_timer,
- ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_prune_pending_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
+ event_add_timer_msec(router->master,
+ on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
+ event_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
pim_upstream_update_join_desired(pim_ifp->pim,
ch->upstream);
}
/* If we called ifjoin_prune() directly instead, care should
be taken not to use "ch" afterwards since it would be
deleted. */
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- thread_add_timer_msec(router->master,
- on_ifjoin_prune_pending_timer, ch,
- jp_override_interval_msec,
- &ch->t_ifjoin_prune_pending_timer);
+ EVENT_OFF(ch->t_ifjoin_prune_pending_timer);
+ event_add_timer_msec(router->master,
+ on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
break;
case PIM_IFJOIN_PRUNE:
if (source_flags & PIM_ENCODE_RPT_BIT) {
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ EVENT_OFF(ch->t_ifjoin_prune_pending_timer);
/*
* While in Prune State, Receive SGRpt Prune.
* RFC 7761 Sec 4.5.3:
* Join/Prune message.
*/
if (ch->t_ifjoin_expiry_timer) {
- unsigned long rem = thread_timer_remain_second(
+ unsigned long rem = event_timer_remain_second(
ch->t_ifjoin_expiry_timer);
if (rem > holdtime)
return;
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
}
- thread_add_timer(router->master, on_ifjoin_expiry_timer,
- ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
+ event_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_TMP:
if (source_flags & PIM_ENCODE_RPT_BIT) {
ch->ifjoin_state = PIM_IFJOIN_PRUNE;
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer(router->master, on_ifjoin_expiry_timer,
- ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
+ event_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_PENDING_TMP:
if (source_flags & PIM_ENCODE_RPT_BIT) {
ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer(router->master, on_ifjoin_expiry_timer,
- ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
+ EVENT_OFF(ch->t_ifjoin_expiry_timer);
+ event_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
}
break;
if (child->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING_TMP)
- THREAD_OFF(child->t_ifjoin_prune_pending_timer);
- THREAD_OFF(child->t_ifjoin_expiry_timer);
+ EVENT_OFF(child->t_ifjoin_prune_pending_timer);
+ EVENT_OFF(child->t_ifjoin_expiry_timer);
PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
child->ifjoin_state = PIM_IFJOIN_NOINFO;
/* Per-interface (S,G) Join/Prune State (Section 4.1.4 of RFC4601) */
enum pim_ifjoin_state ifjoin_state;
- struct thread *t_ifjoin_expiry_timer;
- struct thread *t_ifjoin_prune_pending_timer;
+ struct event *t_ifjoin_expiry_timer;
+ struct event *t_ifjoin_prune_pending_timer;
int64_t ifjoin_creation; /* Record uptime of ifjoin state */
/* Per-interface (S,G) Assert State (Section 4.6.1 of RFC4601) */
enum pim_ifassert_state ifassert_state;
- struct thread *t_ifassert_timer;
+ struct event *t_ifassert_timer;
pim_addr ifassert_winner;
struct pim_assert_metric ifassert_winner_metric;
int64_t ifassert_creation; /* Record uptime of ifassert state */
#include "pim_tib.h"
static void group_timer_off(struct gm_group *group);
-static void pim_igmp_general_query(struct thread *t);
+static void pim_igmp_general_query(struct event *t);
void igmp_anysource_forward_start(struct pim_instance *pim,
struct gm_group *group)
return NULL;
}
-static void pim_igmp_other_querier_expire(struct thread *t)
+static void pim_igmp_other_querier_expire(struct event *t)
{
struct gm_sock *igmp;
- igmp = THREAD_ARG(t);
+ igmp = EVENT_ARG(t);
assert(!igmp->t_igmp_query_timer);
"Querier %s resetting TIMER event for Other-Querier-Present",
ifaddr_str);
}
- THREAD_OFF(igmp->t_other_querier_timer);
+ EVENT_OFF(igmp->t_other_querier_timer);
} else {
/*
We are the current querier, then stop sending general queries:
other_querier_present_interval_msec % 1000);
}
- thread_add_timer_msec(router->master, pim_igmp_other_querier_expire,
- igmp, other_querier_present_interval_msec,
- &igmp->t_other_querier_timer);
+ event_add_timer_msec(router->master, pim_igmp_other_querier_expire,
+ igmp, other_querier_present_interval_msec,
+ &igmp->t_other_querier_timer);
}
void pim_igmp_other_querier_timer_off(struct gm_sock *igmp)
ifaddr_str, igmp->fd, igmp->interface->name);
}
}
- THREAD_OFF(igmp->t_other_querier_timer);
+ EVENT_OFF(igmp->t_other_querier_timer);
}
int igmp_validate_checksum(char *igmp_msg, int igmp_msg_len)
ifaddr_str, query_interval,
startup_mode ? "startup" : "non-startup", igmp->fd);
}
- thread_add_timer(router->master, pim_igmp_general_query, igmp,
- query_interval, &igmp->t_igmp_query_timer);
+ event_add_timer(router->master, pim_igmp_general_query, igmp,
+ query_interval, &igmp->t_igmp_query_timer);
}
void pim_igmp_general_query_off(struct gm_sock *igmp)
ifaddr_str, igmp->fd, igmp->interface->name);
}
}
- THREAD_OFF(igmp->t_igmp_query_timer);
+ EVENT_OFF(igmp->t_igmp_query_timer);
}
/* Issue IGMP general query */
-static void pim_igmp_general_query(struct thread *t)
+static void pim_igmp_general_query(struct event *t)
{
struct gm_sock *igmp;
struct in_addr dst_addr;
struct pim_interface *pim_ifp;
int query_buf_size;
- igmp = THREAD_ARG(t);
+ igmp = EVENT_ARG(t);
assert(igmp->interface);
assert(igmp->interface->info);
igmp->interface->name);
}
}
- THREAD_OFF(igmp->t_igmp_read);
+ EVENT_OFF(igmp->t_igmp_read);
if (close(igmp->fd)) {
flog_err(
igmp_source_delete(src);
}
- THREAD_OFF(group->t_group_query_retransmit_timer);
+ EVENT_OFF(group->t_group_query_retransmit_timer);
group_timer_off(group);
igmp_group_count_decr(pim_ifp);
static void igmp_read_on(struct gm_sock *igmp);
-static void pim_igmp_read(struct thread *t)
+static void pim_igmp_read(struct event *t)
{
uint8_t buf[10000];
- struct gm_sock *igmp = (struct gm_sock *)THREAD_ARG(t);
+ struct gm_sock *igmp = (struct gm_sock *)EVENT_ARG(t);
struct sockaddr_storage from;
struct sockaddr_storage to;
socklen_t fromlen = sizeof(from);
zlog_debug("Scheduling READ event on IGMP socket fd=%d",
igmp->fd);
}
- thread_add_read(router->master, pim_igmp_read, igmp, igmp->fd,
- &igmp->t_igmp_read);
+ event_add_read(router->master, pim_igmp_read, igmp, igmp->fd,
+ &igmp->t_igmp_read);
}
struct gm_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
source records. Source records whose timers are zero (from the
previous EXCLUDE mode) are deleted.
*/
-static void igmp_group_timer(struct thread *t)
+static void igmp_group_timer(struct event *t)
{
struct gm_group *group;
- group = THREAD_ARG(t);
+ group = EVENT_ARG(t);
if (PIM_DEBUG_GM_TRACE) {
char group_str[INET_ADDRSTRLEN];
zlog_debug("Cancelling TIMER event for group %s on %s",
group_str, group->interface->name);
}
- THREAD_OFF(group->t_group_timer);
+ EVENT_OFF(group->t_group_timer);
}
void igmp_group_timer_on(struct gm_group *group, long interval_msec,
*/
assert(group->group_filtermode_isexcl);
- thread_add_timer_msec(router->master, igmp_group_timer, group,
- interval_msec, &group->t_group_timer);
+ event_add_timer_msec(router->master, igmp_group_timer, group,
+ interval_msec, &group->t_group_timer);
}
struct gm_group *find_group_by_addr(struct gm_sock *igmp,
pim_addr ifaddr;
time_t sock_creation;
- struct thread *t_igmp_read; /* read: IGMP sockets */
- struct thread
- *t_igmp_query_timer; /* timer: issue IGMP general queries */
- struct thread *t_other_querier_timer; /* timer: other querier present */
+ struct event *t_igmp_read; /* read: IGMP sockets */
+ /* timer: issue IGMP general queries */
+ struct event *t_igmp_query_timer;
+ struct event *t_other_querier_timer; /* timer: other querier present */
pim_addr querier_addr; /* IP address of the querier */
int querier_query_interval; /* QQI */
int querier_robustness_variable; /* QRV */
struct gm_source {
pim_addr source_addr;
- struct thread *t_source_timer;
+ struct event *t_source_timer;
struct gm_group *source_group; /* back pointer */
time_t source_creation;
uint32_t source_flags;
represents the time for the *filter-mode* of the group to expire and
switch to INCLUDE mode.
*/
- struct thread *t_group_timer;
+ struct event *t_group_timer;
/* Shared between group-specific and
group-and-source-specific retransmissions */
- struct thread *t_group_query_retransmit_timer;
+ struct event *t_group_query_retransmit_timer;
/* Counter exclusive for group-specific retransmissions
(not used by group-and-source-specific retransmissions,
igmp_group_timer_on(group, group_membership_interval_msec, ifp->name);
}
-static void igmp_source_timer(struct thread *t)
+static void igmp_source_timer(struct event *t)
{
struct gm_source *source;
struct gm_group *group;
- source = THREAD_ARG(t);
+ source = EVENT_ARG(t);
group = source->source_group;
group_str, source_str, group->interface->name);
}
- THREAD_OFF(source->t_source_timer);
+ EVENT_OFF(source->t_source_timer);
}
static void igmp_source_timer_on(struct gm_group *group,
source_str, group->interface->name);
}
- thread_add_timer_msec(router->master, igmp_source_timer, source,
- interval_msec, &source->t_source_timer);
+ event_add_timer_msec(router->master, igmp_source_timer, source,
+ interval_msec, &source->t_source_timer);
/*
RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
return num_retransmit_sources_left;
}
-static void igmp_group_retransmit(struct thread *t)
+static void igmp_group_retransmit(struct event *t)
{
struct gm_group *group;
int num_retransmit_sources_left;
int send_with_sflag_set; /* boolean */
- group = THREAD_ARG(t);
+ group = EVENT_ARG(t);
if (PIM_DEBUG_GM_TRACE) {
char group_str[INET_ADDRSTRLEN];
group->interface->name);
}
- thread_add_timer_msec(router->master, igmp_group_retransmit, group,
- lmqi_msec,
- &group->t_group_query_retransmit_timer);
+ event_add_timer_msec(router->master, igmp_group_retransmit, group,
+ lmqi_msec, &group->t_group_query_retransmit_timer);
}
static long igmp_group_timer_remain_msec(struct gm_group *group)
pim_bsm_proc_free(pim);
/* Traverse and cleanup rpf_hash */
- if (pim->rpf_hash) {
- hash_clean(pim->rpf_hash, (void *)pim_rp_list_hash_clean);
- hash_free(pim->rpf_hash);
- pim->rpf_hash = NULL;
- }
+ hash_clean_and_free(&pim->rpf_hash, (void *)pim_rp_list_hash_clean);
pim_if_terminate(pim);
};
struct pim_router {
- struct thread_master *master;
+ struct event_loop *master;
uint32_t debugs;
/* Holds the client data(unencoded) that need to be pushed to MCLAGD*/
struct stream_fifo *mlag_fifo;
struct stream *mlag_stream;
- struct thread *zpthread_mlag_write;
+ struct event *zpthread_mlag_write;
struct in_addr anycast_vtep_ip;
struct in_addr local_vtep_ip;
struct pim_mlag_stats mlag_stats;
int send_v6_secondary;
- struct thread *thread;
+ struct event *thread;
int mroute_socket;
int reg_sock; /* Socket to send register msg */
int64_t mroute_socket_creation;
unsigned int gm_socket_if_count;
int gm_socket;
- struct thread *t_gm_recv;
+ struct event *t_gm_recv;
unsigned int gm_group_count;
unsigned int gm_watermark_limit;
uint64_t bsm_dropped;
/* If we need to rescan all our upstreams */
- struct thread *rpf_cache_refresher;
+ struct event *rpf_cache_refresher;
int64_t rpf_cache_refresh_requests;
int64_t rpf_cache_refresh_events;
int64_t rpf_cache_refresh_last;
if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) {
if (child->ifjoin_state
== PIM_IFJOIN_PRUNE_PENDING_TMP)
- THREAD_OFF(
+ EVENT_OFF(
child->t_ifjoin_prune_pending_timer);
- THREAD_OFF(
- child->t_ifjoin_expiry_timer);
+ EVENT_OFF(child->t_ifjoin_expiry_timer);
PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
child->ifjoin_state = PIM_IFJOIN_NOINFO;
delete_on_noinfo(child);
#include "lib/version.h"
#include <getopt.h>
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include <signal.h>
#include "memory.h"
return 0;
}
-static void pim_mlag_register_handler(struct thread *thread)
+static void pim_mlag_register_handler(struct event *thread)
{
uint32_t bit_mask = 0;
router->mlag_process_register = true;
- thread_add_event(router->master, pim_mlag_register_handler, NULL, 0,
- NULL);
+ event_add_event(router->master, pim_mlag_register_handler, NULL, 0,
+ NULL);
}
-static void pim_mlag_deregister_handler(struct thread *thread)
+static void pim_mlag_deregister_handler(struct event *thread)
{
if (!zclient)
return;
router->mlag_process_register = false;
- thread_add_event(router->master, pim_mlag_deregister_handler, NULL, 0,
- NULL);
+ event_add_event(router->master, pim_mlag_deregister_handler, NULL, 0,
+ NULL);
}
void pim_if_configure_mlag_dualactive(struct pim_interface *pim_ifp)
return 0;
}
-static void mroute_read(struct thread *t)
+static void mroute_read(struct event *t)
{
struct pim_instance *pim;
static long long count;
int cont = 1;
int rd;
ifindex_t ifindex;
- pim = THREAD_ARG(t);
+ pim = EVENT_ARG(t);
while (cont) {
rd = pim_socket_recvfromto(pim->mroute_socket, (uint8_t *)buf,
static void mroute_read_on(struct pim_instance *pim)
{
- thread_add_read(router->master, mroute_read, pim, pim->mroute_socket,
- &pim->thread);
+ event_add_read(router->master, mroute_read, pim, pim->mroute_socket,
+ &pim->thread);
}
static void mroute_read_off(struct pim_instance *pim)
{
- THREAD_OFF(pim->thread);
+ EVENT_OFF(pim->thread);
}
int pim_mroute_socket_enable(struct pim_instance *pim)
#include <lib/prefix.h>
#include <lib/sockunion.h>
#include <lib/stream.h>
-#include <lib/thread.h>
+#include <frrevent.h>
#include <lib/vty.h>
#include <lib/plist.h>
#include <lib/lib_errors.h>
}
/* RFC-3618:Sec-5.1 - global active source advertisement timer */
-static void pim_msdp_sa_adv_timer_cb(struct thread *t)
+static void pim_msdp_sa_adv_timer_cb(struct event *t)
{
- struct pim_instance *pim = THREAD_ARG(t);
+ struct pim_instance *pim = EVENT_ARG(t);
if (PIM_DEBUG_MSDP_EVENTS) {
zlog_debug("MSDP SA advertisement timer expired");
static void pim_msdp_sa_adv_timer_setup(struct pim_instance *pim, bool start)
{
- THREAD_OFF(pim->msdp.sa_adv_timer);
+ EVENT_OFF(pim->msdp.sa_adv_timer);
if (start) {
- thread_add_timer(pim->msdp.master, pim_msdp_sa_adv_timer_cb,
- pim, PIM_MSDP_SA_ADVERTISMENT_TIME,
- &pim->msdp.sa_adv_timer);
+ event_add_timer(pim->msdp.master, pim_msdp_sa_adv_timer_cb, pim,
+ PIM_MSDP_SA_ADVERTISMENT_TIME,
+ &pim->msdp.sa_adv_timer);
}
}
/* RFC-3618:Sec-5.3 - SA cache state timer */
-static void pim_msdp_sa_state_timer_cb(struct thread *t)
+static void pim_msdp_sa_state_timer_cb(struct event *t)
{
struct pim_msdp_sa *sa;
- sa = THREAD_ARG(t);
+ sa = EVENT_ARG(t);
if (PIM_DEBUG_MSDP_EVENTS) {
pim_msdp_sa_timer_expiry_log(sa, "state");
static void pim_msdp_sa_state_timer_setup(struct pim_msdp_sa *sa, bool start)
{
- THREAD_OFF(sa->sa_state_timer);
+ EVENT_OFF(sa->sa_state_timer);
if (start) {
- thread_add_timer(sa->pim->msdp.master,
- pim_msdp_sa_state_timer_cb, sa,
- PIM_MSDP_SA_HOLD_TIME, &sa->sa_state_timer);
+ event_add_timer(sa->pim->msdp.master,
+ pim_msdp_sa_state_timer_cb, sa,
+ PIM_MSDP_SA_HOLD_TIME, &sa->sa_state_timer);
}
}
}
/* RFC-3618:Sec-5.4 - peer hold timer */
-static void pim_msdp_peer_hold_timer_cb(struct thread *t)
+static void pim_msdp_peer_hold_timer_cb(struct event *t)
{
struct pim_msdp_peer *mp;
- mp = THREAD_ARG(t);
+ mp = EVENT_ARG(t);
if (PIM_DEBUG_MSDP_EVENTS) {
pim_msdp_peer_timer_expiry_log(mp, "hold");
static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start)
{
struct pim_instance *pim = mp->pim;
- THREAD_OFF(mp->hold_timer);
+ EVENT_OFF(mp->hold_timer);
if (start) {
- thread_add_timer(pim->msdp.master, pim_msdp_peer_hold_timer_cb,
- mp, pim->msdp.hold_time, &mp->hold_timer);
+ event_add_timer(pim->msdp.master, pim_msdp_peer_hold_timer_cb,
+ mp, pim->msdp.hold_time, &mp->hold_timer);
}
}
/* RFC-3618:Sec-5.5 - peer keepalive timer */
-static void pim_msdp_peer_ka_timer_cb(struct thread *t)
+static void pim_msdp_peer_ka_timer_cb(struct event *t)
{
struct pim_msdp_peer *mp;
- mp = THREAD_ARG(t);
+ mp = EVENT_ARG(t);
if (PIM_DEBUG_MSDP_EVENTS) {
pim_msdp_peer_timer_expiry_log(mp, "ka");
static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start)
{
- THREAD_OFF(mp->ka_timer);
+ EVENT_OFF(mp->ka_timer);
if (start) {
- thread_add_timer(mp->pim->msdp.master,
- pim_msdp_peer_ka_timer_cb, mp,
- mp->pim->msdp.keep_alive, &mp->ka_timer);
+ event_add_timer(mp->pim->msdp.master, pim_msdp_peer_ka_timer_cb,
+ mp, mp->pim->msdp.keep_alive, &mp->ka_timer);
}
}
}
/* RFC-3618:Sec-5.6 - connection retry on active peer */
-static void pim_msdp_peer_cr_timer_cb(struct thread *t)
+static void pim_msdp_peer_cr_timer_cb(struct event *t)
{
struct pim_msdp_peer *mp;
- mp = THREAD_ARG(t);
+ mp = EVENT_ARG(t);
if (PIM_DEBUG_MSDP_EVENTS) {
pim_msdp_peer_timer_expiry_log(mp, "connect-retry");
static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start)
{
- THREAD_OFF(mp->cr_timer);
+ EVENT_OFF(mp->cr_timer);
if (start) {
- thread_add_timer(mp->pim->msdp.master,
- pim_msdp_peer_cr_timer_cb, mp,
- mp->pim->msdp.connection_retry, &mp->cr_timer);
+ event_add_timer(mp->pim->msdp.master, pim_msdp_peer_cr_timer_cb,
+ mp, mp->pim->msdp.connection_retry,
+ &mp->cr_timer);
}
}
}
/* MSDP init */
-void pim_msdp_init(struct pim_instance *pim, struct thread_master *master)
+void pim_msdp_init(struct pim_instance *pim, struct event_loop *master)
{
pim->msdp.master = master;
char hash_name[64];
while ((mg = SLIST_FIRST(&pim->msdp.mglist)) != NULL)
pim_msdp_mg_free(pim, &mg);
- if (pim->msdp.peer_hash) {
- hash_clean(pim->msdp.peer_hash, NULL);
- hash_free(pim->msdp.peer_hash);
- pim->msdp.peer_hash = NULL;
- }
+ hash_clean_and_free(&pim->msdp.peer_hash, NULL);
if (pim->msdp.peer_list) {
list_delete(&pim->msdp.peer_list);
}
- if (pim->msdp.sa_hash) {
- hash_clean(pim->msdp.sa_hash, NULL);
- hash_free(pim->msdp.sa_hash);
- pim->msdp.sa_hash = NULL;
- }
+ hash_clean_and_free(&pim->msdp.sa_hash, NULL);
if (pim->msdp.sa_list) {
list_delete(&pim->msdp.sa_list);
/* rfc-3618 is missing default value for SA-hold-down-Period. pulled
* this number from industry-standards */
#define PIM_MSDP_SA_HOLD_TIME ((3*60)+30)
- struct thread *sa_state_timer; // 5.6
+ struct event *sa_state_timer; // 5.6
int64_t uptime;
struct pim_upstream *up;
/* protocol timers */
#define PIM_MSDP_PEER_HOLD_TIME 75
- struct thread *hold_timer; // 5.4
+ struct event *hold_timer; // 5.4
#define PIM_MSDP_PEER_KA_TIME 60
- struct thread *ka_timer; // 5.5
+ struct event *ka_timer; // 5.5
#define PIM_MSDP_PEER_CONNECT_RETRY_TIME 30
- struct thread *cr_timer; // 5.6
+ struct event *cr_timer; // 5.6
/* packet thread and buffers */
uint32_t packet_size;
struct stream *ibuf;
struct stream_fifo *obuf;
- struct thread *t_read;
- struct thread *t_write;
+ struct event *t_read;
+ struct event *t_write;
/* stats */
uint32_t conn_attempts;
struct pim_msdp_listener {
int fd;
union sockunion su;
- struct thread *thread;
+ struct event *thread;
};
struct pim_msdp {
enum pim_msdp_flags flags;
- struct thread_master *master;
+ struct event_loop *master;
struct pim_msdp_listener listener;
uint32_t rejected_accepts;
/* MSDP active-source info */
#define PIM_MSDP_SA_ADVERTISMENT_TIME 60
- struct thread *sa_adv_timer; // 5.6
+ struct event *sa_adv_timer; // 5.6
struct hash *sa_hash;
struct list *sa_list;
uint32_t local_cnt;
};
#define PIM_MSDP_PEER_READ_ON(mp) \
- thread_add_read(mp->pim->msdp.master, pim_msdp_read, mp, mp->fd, \
- &mp->t_read)
+ event_add_read(mp->pim->msdp.master, pim_msdp_read, mp, mp->fd, \
+ &mp->t_read)
#define PIM_MSDP_PEER_WRITE_ON(mp) \
- thread_add_write(mp->pim->msdp.master, pim_msdp_write, mp, mp->fd, \
- &mp->t_write)
+ event_add_write(mp->pim->msdp.master, pim_msdp_write, mp, mp->fd, \
+ &mp->t_write)
-#define PIM_MSDP_PEER_READ_OFF(mp) thread_cancel(&mp->t_read)
-#define PIM_MSDP_PEER_WRITE_OFF(mp) thread_cancel(&mp->t_write)
+#define PIM_MSDP_PEER_READ_OFF(mp) event_cancel(&mp->t_read)
+#define PIM_MSDP_PEER_WRITE_OFF(mp) event_cancel(&mp->t_write)
#if PIM_IPV != 6
// struct pim_msdp *msdp;
struct pim_instance;
-void pim_msdp_init(struct pim_instance *pim, struct thread_master *master);
+void pim_msdp_init(struct pim_instance *pim, struct event_loop *master);
void pim_msdp_exit(struct pim_instance *pim);
char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf,
int buf_size);
void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp);
void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state);
void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str);
-void pim_msdp_write(struct thread *thread);
+void pim_msdp_write(struct event *thread);
int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
const char *spaces);
bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
#else /* PIM_IPV == 6 */
static inline void pim_msdp_init(struct pim_instance *pim,
- struct thread_master *master)
+ struct event_loop *master)
{
}
#include <lib/log.h>
#include <lib/network.h>
#include <lib/stream.h>
-#include <lib/thread.h>
+#include "frrevent.h"
#include <lib/vty.h>
#include <lib/lib_errors.h>
}
}
-void pim_msdp_write(struct thread *thread)
+void pim_msdp_write(struct event *thread)
{
struct pim_msdp_peer *mp;
struct stream *s;
int work_cnt = 0;
int work_max_cnt = 100;
- mp = THREAD_ARG(thread);
+ mp = EVENT_ARG(thread);
mp->t_write = NULL;
if (PIM_DEBUG_MSDP_INTERNAL) {
return 0;
}
-void pim_msdp_read(struct thread *thread)
+void pim_msdp_read(struct event *thread)
{
struct pim_msdp_peer *mp;
int rc;
uint32_t len;
- mp = THREAD_ARG(thread);
+ mp = EVENT_ARG(thread);
mp->t_read = NULL;
if (PIM_DEBUG_MSDP_INTERNAL) {
#define PIM_MSDP_PKT_TYPE_STRLEN 16
void pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp);
-void pim_msdp_read(struct thread *thread);
+void pim_msdp_read(struct event *thread);
void pim_msdp_pkt_sa_tx(struct pim_instance *pim);
void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa);
void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp);
#include <lib/log.h>
#include <lib/network.h>
#include <lib/sockunion.h>
-#include <lib/thread.h>
+#include "frrevent.h"
#include <lib/vty.h>
#include <lib/if.h>
#include <lib/vrf.h>
}
/* passive peer socket accept */
-static void pim_msdp_sock_accept(struct thread *thread)
+static void pim_msdp_sock_accept(struct event *thread)
{
union sockunion su;
- struct pim_instance *pim = THREAD_ARG(thread);
+ struct pim_instance *pim = EVENT_ARG(thread);
int accept_sock;
int msdp_sock;
struct pim_msdp_peer *mp;
sockunion_init(&su);
/* re-register accept thread */
- accept_sock = THREAD_FD(thread);
+ accept_sock = EVENT_FD(thread);
if (accept_sock < 0) {
flog_err(EC_LIB_DEVELOPMENT, "accept_sock is negative value %d",
accept_sock);
return;
}
pim->msdp.listener.thread = NULL;
- thread_add_read(router->master, pim_msdp_sock_accept, pim, accept_sock,
- &pim->msdp.listener.thread);
+ event_add_read(router->master, pim_msdp_sock_accept, pim, accept_sock,
+ &pim->msdp.listener.thread);
/* accept client connection. */
msdp_sock = sockunion_accept(accept_sock, &su);
/* add accept thread */
listener->fd = sock;
memcpy(&listener->su, &sin, socklen);
- thread_add_read(pim->msdp.master, pim_msdp_sock_accept, pim, sock,
- &listener->thread);
+ event_add_read(pim->msdp.master, pim_msdp_sock_accept, pim, sock,
+ &listener->thread);
pim->msdp.flags |= PIM_MSDPF_LISTENER;
return 0;
}
}
-static void on_neighbor_timer(struct thread *t)
+static void on_neighbor_timer(struct event *t)
{
struct pim_neighbor *neigh;
struct interface *ifp;
char msg[100];
- neigh = THREAD_ARG(t);
+ neigh = EVENT_ARG(t);
ifp = neigh->interface;
{
neigh->holdtime = holdtime;
- THREAD_OFF(neigh->t_expire_timer);
+ EVENT_OFF(neigh->t_expire_timer);
/*
0xFFFF is request for no holdtime
__func__, neigh->holdtime, &neigh->source_addr,
neigh->interface->name);
- thread_add_timer(router->master, on_neighbor_timer, neigh,
- neigh->holdtime, &neigh->t_expire_timer);
+ event_add_timer(router->master, on_neighbor_timer, neigh,
+ neigh->holdtime, &neigh->t_expire_timer);
}
-static void on_neighbor_jp_timer(struct thread *t)
+static void on_neighbor_jp_timer(struct event *t)
{
- struct pim_neighbor *neigh = THREAD_ARG(t);
+ struct pim_neighbor *neigh = EVENT_ARG(t);
struct pim_rpf rpf;
if (PIM_DEBUG_PIM_TRACE)
rpf.rpf_addr = neigh->source_addr;
pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
- thread_add_timer(router->master, on_neighbor_jp_timer, neigh,
- router->t_periodic, &neigh->jp_timer);
+ event_add_timer(router->master, on_neighbor_jp_timer, neigh,
+ router->t_periodic, &neigh->jp_timer);
}
static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh)
{
- THREAD_OFF(neigh->jp_timer);
- thread_add_timer(router->master, on_neighbor_jp_timer, neigh,
- router->t_periodic, &neigh->jp_timer);
+ EVENT_OFF(neigh->jp_timer);
+ event_add_timer(router->master, on_neighbor_jp_timer, neigh,
+ router->t_periodic, &neigh->jp_timer);
}
static struct pim_neighbor *
delete_prefix_list(neigh);
list_delete(&neigh->upstream_jp_agg);
- THREAD_OFF(neigh->jp_timer);
+ EVENT_OFF(neigh->jp_timer);
bfd_sess_free(&neigh->bfd_session);
zlog_notice("PIM NEIGHBOR DOWN: neighbor %pPA on interface %s: %s",
&neigh->source_addr, ifp->name, delete_message);
- THREAD_OFF(neigh->t_expire_timer);
+ EVENT_OFF(neigh->t_expire_timer);
pim_if_assert_on_neighbor_down(ifp, neigh->source_addr);
uint32_t dr_priority;
uint32_t generation_id;
struct list *prefix_list; /* list of struct prefix */
- struct thread *t_expire_timer;
+ struct event *t_expire_timer;
struct interface *interface;
- struct thread *jp_timer;
+ struct event *jp_timer;
struct list *upstream_jp_agg;
struct bfd_session_params *bfd_session;
};
#include <zebra.h>
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "if.h"
#include "network.h"
#include "pim_bsm.h"
#include <lib/lib_errors.h>
-static void on_pim_hello_send(struct thread *t);
+static void on_pim_hello_send(struct event *t);
static const char *pim_pim_msgtype2str(enum pim_msg_type type)
{
pim_ifp->pim_sock_fd, ifp->name);
}
}
- THREAD_OFF(pim_ifp->t_pim_sock_read);
+ EVENT_OFF(pim_ifp->t_pim_sock_read);
if (PIM_DEBUG_PIM_TRACE) {
if (pim_ifp->t_pim_hello_timer) {
ifp->name);
}
}
- THREAD_OFF(pim_ifp->t_pim_hello_timer);
+ EVENT_OFF(pim_ifp->t_pim_hello_timer);
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug("Deleting PIM socket fd=%d on interface %s",
static void pim_sock_read_on(struct interface *ifp);
-static void pim_sock_read(struct thread *t)
+static void pim_sock_read(struct event *t)
{
struct interface *ifp, *orig_ifp;
struct pim_interface *pim_ifp;
static long long count = 0;
int cont = 1;
- orig_ifp = ifp = THREAD_ARG(t);
- fd = THREAD_FD(t);
+ orig_ifp = ifp = EVENT_ARG(t);
+ fd = EVENT_FD(t);
pim_ifp = ifp->info;
zlog_debug("Scheduling READ event on PIM socket fd=%d",
pim_ifp->pim_sock_fd);
}
- thread_add_read(router->master, pim_sock_read, ifp,
- pim_ifp->pim_sock_fd, &pim_ifp->t_pim_sock_read);
+ event_add_read(router->master, pim_sock_read, ifp, pim_ifp->pim_sock_fd,
+ &pim_ifp->t_pim_sock_read);
}
static int pim_sock_open(struct interface *ifp)
zlog_debug("Rescheduling %d sec hello on interface %s",
pim_ifp->pim_hello_period, ifp->name);
}
- THREAD_OFF(pim_ifp->t_pim_hello_timer);
- thread_add_timer(router->master, on_pim_hello_send, ifp,
- pim_ifp->pim_hello_period,
- &pim_ifp->t_pim_hello_timer);
+ EVENT_OFF(pim_ifp->t_pim_hello_timer);
+ event_add_timer(router->master, on_pim_hello_send, ifp,
+ pim_ifp->pim_hello_period, &pim_ifp->t_pim_hello_timer);
}
/*
Periodic hello timer
*/
-static void on_pim_hello_send(struct thread *t)
+static void on_pim_hello_send(struct event *t)
{
struct pim_interface *pim_ifp;
struct interface *ifp;
- ifp = THREAD_ARG(t);
+ ifp = EVENT_ARG(t);
pim_ifp = ifp->info;
/*
return;
}
- THREAD_OFF(pim_ifp->t_pim_hello_timer);
+ EVENT_OFF(pim_ifp->t_pim_hello_timer);
}
random_msec = triggered_hello_delay_msec;
random_msec, ifp->name);
}
- thread_add_timer_msec(router->master, on_pim_hello_send, ifp,
- random_msec, &pim_ifp->t_pim_hello_timer);
+ event_add_timer_msec(router->master, on_pim_hello_send, ifp,
+ random_msec, &pim_ifp->t_pim_hello_timer);
}
int pim_sock_add(struct interface *ifp)
#include "log.h"
#include "if.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "vty.h"
#include "plist.h"
#include "pim_vxlan.h"
#include "pim_addr.h"
-struct thread *send_test_packet_timer = NULL;
+struct event *send_test_packet_timer = NULL;
void pim_register_join(struct pim_upstream *up)
{
&& (up->reg_state != PIM_REG_NOINFO)) {
pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM, __func__);
- THREAD_OFF(up->t_rs_timer);
+ EVENT_OFF(up->t_rs_timer);
up->reg_state = PIM_REG_NOINFO;
}
}
list_delete(&pnc->rp_list);
- hash_clean(pnc->upstream_hash, NULL);
- hash_free(pnc->upstream_hash);
- pnc->upstream_hash = NULL;
+ hash_clean_and_free(&pnc->upstream_hash, NULL);
if (pnc->nexthop)
nexthops_free(pnc->nexthop);
{
assert(ss);
- THREAD_OFF(ss->t_sock_read);
+ EVENT_OFF(ss->t_sock_read);
if (close(ss->sock_fd)) {
zlog_warn(
return 0;
}
-static void ssmpingd_sock_read(struct thread *t)
+static void ssmpingd_sock_read(struct event *t)
{
struct ssmpingd_sock *ss;
- ss = THREAD_ARG(t);
+ ss = EVENT_ARG(t);
ssmpingd_read_msg(ss);
static void ssmpingd_read_on(struct ssmpingd_sock *ss)
{
- thread_add_read(router->master, ssmpingd_sock_read, ss, ss->sock_fd,
- &ss->t_sock_read);
+ event_add_read(router->master, ssmpingd_sock_read, ss, ss->sock_fd,
+ &ss->t_sock_read);
}
static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim,
struct pim_instance *pim;
int sock_fd; /* socket */
- struct thread *t_sock_read; /* thread for reading socket */
+ struct event *t_sock_read; /* thread for reading socket */
pim_addr source_addr; /* source address */
int64_t creation; /* timestamp of socket creation */
int64_t requests; /* counter */
#include <time.h>
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "lib_errors.h"
#include "pim_time.h"
return wr != 8;
}
-void pim_time_timer_to_mmss(char *buf, int buf_size, struct thread *t_timer)
+void pim_time_timer_to_mmss(char *buf, int buf_size, struct event *t_timer)
{
if (t_timer) {
pim_time_mmss(buf, buf_size,
- thread_timer_remain_second(t_timer));
+ event_timer_remain_second(t_timer));
} else {
snprintf(buf, buf_size, "--:--");
}
}
-void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct thread *t_timer)
+void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct event *t_timer)
{
if (t_timer) {
pim_time_hhmmss(buf, buf_size,
- thread_timer_remain_second(t_timer));
+ event_timer_remain_second(t_timer));
} else {
snprintf(buf, buf_size, "--:--:--");
}
snprintf(buf, buf_size, "--:--:--");
}
-long pim_time_timer_remain_msec(struct thread *t_timer)
+long pim_time_timer_remain_msec(struct event *t_timer)
{
/* no timer thread running means timer has expired: return 0 */
- return t_timer ? thread_timer_remain_msec(t_timer) : 0;
+ return t_timer ? event_timer_remain_msec(t_timer) : 0;
}
#include <stdint.h>
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
int64_t pim_time_monotonic_sec(void);
int64_t pim_time_monotonic_dsec(void);
int64_t pim_time_monotonic_usec(void);
int pim_time_mmss(char *buf, int buf_size, long sec);
-void pim_time_timer_to_mmss(char *buf, int buf_size, struct thread *t);
-void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct thread *t);
+void pim_time_timer_to_mmss(char *buf, int buf_size, struct event *t);
+void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct event *t);
void pim_time_uptime(char *buf, int buf_size, int64_t uptime_sec);
void pim_time_uptime_begin(char *buf, int buf_size, int64_t now, int64_t begin);
-long pim_time_timer_remain_msec(struct thread *t_timer);
+long pim_time_timer_remain_msec(struct event *t_timer);
#endif /* PIM_TIME_H */
#include "log.h"
#include "zclient.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "plist.h"
static void pim_upstream_timers_stop(struct pim_upstream *up)
{
- THREAD_OFF(up->t_ka_timer);
- THREAD_OFF(up->t_rs_timer);
- THREAD_OFF(up->t_msdp_reg_timer);
- THREAD_OFF(up->t_join_timer);
+ EVENT_OFF(up->t_ka_timer);
+ EVENT_OFF(up->t_rs_timer);
+ EVENT_OFF(up->t_msdp_reg_timer);
+ EVENT_OFF(up->t_join_timer);
}
struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
pim_jp_agg_single_upstream_send(&up->rpf, up, 1 /* join */);
}
-static void on_join_timer(struct thread *t)
+static void on_join_timer(struct event *t)
{
struct pim_upstream *up;
- up = THREAD_ARG(t);
+ up = EVENT_ARG(t);
if (!up->rpf.source_nexthop.interface) {
if (PIM_DEBUG_PIM_TRACE)
{
struct pim_neighbor *nbr = NULL;
- THREAD_OFF(up->t_join_timer);
+ EVENT_OFF(up->t_join_timer);
if (up->rpf.source_nexthop.interface)
nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
if (nbr)
pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1, nbr);
else {
- THREAD_OFF(up->t_join_timer);
- thread_add_timer(router->master, on_join_timer, up,
- router->t_periodic, &up->t_join_timer);
+ EVENT_OFF(up->t_join_timer);
+ event_add_timer(router->master, on_join_timer, up,
+ router->t_periodic, &up->t_join_timer);
}
pim_jp_agg_upstream_verification(up, true);
}
void pim_upstream_join_timer_restart(struct pim_upstream *up,
struct pim_rpf *old)
{
- // THREAD_OFF(up->t_join_timer);
+ // EVENT_OFF(up->t_join_timer);
join_timer_start(up);
}
__func__, interval_msec, up->sg_str);
}
- THREAD_OFF(up->t_join_timer);
- thread_add_timer_msec(router->master, on_join_timer, up, interval_msec,
- &up->t_join_timer);
+ EVENT_OFF(up->t_join_timer);
+ event_add_timer_msec(router->master, on_join_timer, up, interval_msec,
+ &up->t_join_timer);
}
void pim_update_suppress_timers(uint32_t suppress_time)
up->sg_str);
/* stop reg-stop timer */
- THREAD_OFF(up->t_rs_timer);
+ EVENT_OFF(up->t_rs_timer);
/* remove regiface from the OIL if it is there*/
pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM, __func__);
return up;
}
-static void pim_upstream_keep_alive_timer(struct thread *t)
+static void pim_upstream_keep_alive_timer(struct event *t)
{
struct pim_upstream *up;
- up = THREAD_ARG(t);
+ up = EVENT_ARG(t);
/* pull the stats and re-check */
if (pim_upstream_sg_running_proc(up))
zlog_debug("kat start on %s with no stream reference",
up->sg_str);
}
- THREAD_OFF(up->t_ka_timer);
- thread_add_timer(router->master, pim_upstream_keep_alive_timer, up,
- time, &up->t_ka_timer);
+ EVENT_OFF(up->t_ka_timer);
+ event_add_timer(router->master, pim_upstream_keep_alive_timer, up, time,
+ &up->t_ka_timer);
/* any time keepalive is started against a SG we will have to
* re-evaluate our active source database */
}
/* MSDP on RP needs to know if a source is registerable to this RP */
-static void pim_upstream_msdp_reg_timer(struct thread *t)
+static void pim_upstream_msdp_reg_timer(struct event *t)
{
- struct pim_upstream *up = THREAD_ARG(t);
+ struct pim_upstream *up = EVENT_ARG(t);
struct pim_instance *pim = up->channel_oil->pim;
/* source is no longer active - pull the SA from MSDP's cache */
void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
{
- THREAD_OFF(up->t_msdp_reg_timer);
- thread_add_timer(router->master, pim_upstream_msdp_reg_timer, up,
- PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
+ EVENT_OFF(up->t_msdp_reg_timer);
+ event_add_timer(router->master, pim_upstream_msdp_reg_timer, up,
+ PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
pim_msdp_sa_local_update(up);
}
return state_str;
}
-static void pim_upstream_register_stop_timer(struct thread *t)
+static void pim_upstream_register_stop_timer(struct event *t)
{
struct pim_interface *pim_ifp;
struct pim_instance *pim;
struct pim_upstream *up;
- up = THREAD_ARG(t);
+ up = EVENT_ARG(t);
pim = up->channel_oil->pim;
if (PIM_DEBUG_PIM_TRACE) {
{
uint32_t time;
- THREAD_OFF(up->t_rs_timer);
+ EVENT_OFF(up->t_rs_timer);
if (!null_register) {
uint32_t lower = (0.5 * router->register_suppress_time);
"%s: (S,G)=%s Starting upstream register stop timer %d",
__func__, up->sg_str, time);
}
- thread_add_timer(router->master, pim_upstream_register_stop_timer, up,
- time, &up->t_rs_timer);
+ event_add_timer(router->master, pim_upstream_register_stop_timer, up,
+ time, &up->t_rs_timer);
}
int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
struct pim_up_mlag mlag;
- struct thread *t_join_timer;
+ struct event *t_join_timer;
/*
* RST(S,G)
*/
- struct thread *t_rs_timer;
+ struct event *t_rs_timer;
#define PIM_REGISTER_SUPPRESSION_PERIOD (60)
#define PIM_REGISTER_PROBE_PERIOD (5)
/*
* KAT(S,G)
*/
- struct thread *t_ka_timer;
+ struct event *t_ka_timer;
#define PIM_KEEPALIVE_PERIOD (210)
#define PIM_RP_KEEPALIVE_PERIOD \
(3 * router->register_suppress_time + router->register_probe_time)
/* on the RP we restart a timer to indicate if registers are being rxed
* for
* SG. This is needed by MSDP to determine its local SA cache */
- struct thread *t_msdp_reg_timer;
+ struct event *t_msdp_reg_timer;
#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * router->register_suppress_time))
int64_t state_transition; /* Record current state uptime */
pim_vxlan_del_work(vxlan_sg);
}
-static void pim_vxlan_work_timer_cb(struct thread *t)
+static void pim_vxlan_work_timer_cb(struct event *t)
{
pim_vxlan_do_reg_work();
pim_vxlan_work_timer_setup(true /* start */);
/* global 1second timer used for periodic processing */
static void pim_vxlan_work_timer_setup(bool start)
{
- THREAD_OFF(vxlan_info.work_timer);
+ EVENT_OFF(vxlan_info.work_timer);
if (start)
- thread_add_timer(router->master, pim_vxlan_work_timer_cb, NULL,
- PIM_VXLAN_WORK_TIME, &vxlan_info.work_timer);
+ event_add_timer(router->master, pim_vxlan_work_timer_cb, NULL,
+ PIM_VXLAN_WORK_TIME, &vxlan_info.work_timer);
}
/**************************** vxlan origination mroutes ***********************
* if there are no other references.
*/
if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
- THREAD_OFF(up->t_ka_timer);
+ EVENT_OFF(up->t_ka_timer);
up = pim_upstream_keep_alive_timer_proc(up);
} else {
/* this is really unexpected as we force vxlan
void pim_vxlan_exit(struct pim_instance *pim)
{
- if (pim->vxlan.sg_hash) {
- hash_clean(pim->vxlan.sg_hash,
- (void (*)(void *))pim_vxlan_sg_del_item);
- hash_free(pim->vxlan.sg_hash);
- pim->vxlan.sg_hash = NULL;
- }
+ hash_clean_and_free(&pim->vxlan.sg_hash,
+ (void (*)(void *))pim_vxlan_sg_del_item);
}
void pim_vxlan_terminate(void)
struct pim_vxlan {
enum pim_vxlan_flags flags;
- struct thread *work_timer;
+ struct event *work_timer;
struct list *work_list;
struct listnode *next_work;
int max_work_cnt;
{
struct interface *ifp;
vrf_id_t new_vrf_id;
+ struct pim_instance *pim;
+ struct pim_interface *pim_ifp;
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
&new_vrf_id);
zlog_debug("%s: %s updating from %u to %u", __func__, ifp->name,
vrf_id, new_vrf_id);
+ pim = pim_get_pim_instance(new_vrf_id);
+
if_update_to_new_vrf(ifp, new_vrf_id);
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return 0;
+
+ pim_ifp->pim->mcast_if_count--;
+ pim_ifp->pim = pim;
+ pim_ifp->pim->mcast_if_count++;
+
return 0;
}
pim_upstream_mroute_iif_update(c_oil, __func__);
}
-static void on_rpf_cache_refresh(struct thread *t)
+static void on_rpf_cache_refresh(struct event *t)
{
- struct pim_instance *pim = THREAD_ARG(t);
+ struct pim_instance *pim = EVENT_ARG(t);
/* update kernel multicast forwarding cache (MFC) */
pim_scan_oil(pim);
router->rpf_cache_refresh_delay_msec);
}
- thread_add_timer_msec(router->master, on_rpf_cache_refresh, pim,
- router->rpf_cache_refresh_delay_msec,
- &pim->rpf_cache_refresher);
+ event_add_timer_msec(router->master, on_rpf_cache_refresh, pim,
+ router->rpf_cache_refresh_delay_msec,
+ &pim->rpf_cache_refresher);
}
static void pim_zebra_connected(struct zclient *zclient)
#include "zclient.h"
#include "stream.h"
#include "network.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "vty.h"
#include "lib_errors.h"
#include "pim_addr.h"
static struct zclient *zlookup = NULL;
-struct thread *zlookup_read;
+struct event *zlookup_read;
static void zclient_lookup_sched(struct zclient *zlookup, int delay);
-static void zclient_lookup_read_pipe(struct thread *thread);
+static void zclient_lookup_read_pipe(struct event *thread);
/* Connect to zebra for nexthop lookup. */
-static void zclient_lookup_connect(struct thread *t)
+static void zclient_lookup_connect(struct event *t)
{
struct zclient *zlookup;
- zlookup = THREAD_ARG(t);
+ zlookup = EVENT_ARG(t);
if (zlookup->sock >= 0) {
return;
return;
}
- thread_add_timer(router->master, zclient_lookup_read_pipe, zlookup, 60,
- &zlookup_read);
+ event_add_timer(router->master, zclient_lookup_read_pipe, zlookup, 60,
+ &zlookup_read);
}
/* Schedule connection with delay. */
static void zclient_lookup_sched(struct zclient *zlookup, int delay)
{
- thread_add_timer(router->master, zclient_lookup_connect, zlookup, delay,
- &zlookup->t_connect);
+ event_add_timer(router->master, zclient_lookup_connect, zlookup, delay,
+ &zlookup->t_connect);
zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
__func__, delay);
/* Schedule connection for now. */
static void zclient_lookup_sched_now(struct zclient *zlookup)
{
- thread_add_event(router->master, zclient_lookup_connect, zlookup, 0,
- &zlookup->t_connect);
+ event_add_event(router->master, zclient_lookup_connect, zlookup, 0,
+ &zlookup->t_connect);
zlog_notice("%s: zclient lookup immediate connection scheduled",
__func__);
void zclient_lookup_free(void)
{
- THREAD_OFF(zlookup_read);
+ EVENT_OFF(zlookup_read);
zclient_stop(zlookup);
zclient_free(zlookup);
zlookup = NULL;
return zclient_read_nexthop(pim, zlookup, nexthop_tab, tab_size, addr);
}
-void zclient_lookup_read_pipe(struct thread *thread)
+void zclient_lookup_read_pipe(struct event *thread)
{
- struct zclient *zlookup = THREAD_ARG(thread);
+ struct zclient *zlookup = EVENT_ARG(thread);
struct pim_instance *pim = pim_get_pim_instance(VRF_DEFAULT);
struct pim_zlookup_nexthop nexthop_tab[10];
pim_addr l = PIMADDR_ANY;
}
zclient_lookup_nexthop_once(pim, nexthop_tab, 10, l);
- thread_add_timer(router->master, zclient_lookup_read_pipe, zlookup, 60,
- &zlookup_read);
+ event_add_timer(router->master, zclient_lookup_read_pipe, zlookup, 60,
+ &zlookup_read);
}
int zclient_lookup_nexthop(struct pim_instance *pim,
* Thsi thread reads the clients data from the Gloabl queue and encodes with
* protobuf and pass on to the MLAG socket.
*/
-static void pim_mlag_zthread_handler(struct thread *event)
+static void pim_mlag_zthread_handler(struct event *event)
{
struct stream *read_s;
uint32_t wr_count = 0;
if (PIM_DEBUG_MLAG)
zlog_debug(":%s: Scheduling PIM MLAG write Thread",
__func__);
- thread_add_event(router->master, pim_mlag_zthread_handler, NULL,
- 0, &router->zpthread_mlag_write);
+ event_add_event(router->master, pim_mlag_zthread_handler, NULL,
+ 0, &router->zpthread_mlag_write);
}
return (0);
}
"lib/routemap.c": "VTYSH_RMAP",
"lib/routemap_cli.c": "VTYSH_RMAP",
"lib/spf_backoff.c": "VTYSH_ISISD",
- "lib/thread.c": "VTYSH_ALL",
+ "lib/event.c": "VTYSH_ALL",
"lib/vrf.c": "VTYSH_VRF",
"lib/vty.c": "VTYSH_ALL",
}
# constants, need to be kept in sync manually...
-XREFT_THREADSCHED = 0x100
+XREFT_EVENTSCHED = 0x100
XREFT_LOGMSG = 0x200
XREFT_DEFUN = 0x300
XREFT_INSTALL_ELEMENT = 0x301
struct = "xref_threadsched"
-Xref.containers[XREFT_THREADSCHED] = XrefThreadSched
+Xref.containers[XREFT_EVENTSCHED] = XrefThreadSched
class XrefLogmsg(ELFDissectStruct, XrelfoJson):
#include "table.h"
#include "log.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "zclient.h"
#include "filter.h"
#include "sockopt.h"
ri->enable_interface = 0;
ri->running = 0;
- THREAD_OFF(ri->t_wakeup);
+ EVENT_OFF(ri->t_wakeup);
}
void rip_interfaces_clean(struct rip *rip)
ri = ifp->info;
- THREAD_OFF(ri->t_wakeup);
+ EVENT_OFF(ri->t_wakeup);
rip = ri->rip;
if (rip) {
}
/* Join to multicast group and send request to the interface. */
-static void rip_interface_wakeup(struct thread *t)
+static void rip_interface_wakeup(struct event *t)
{
struct interface *ifp;
struct rip_interface *ri;
/* Get interface. */
- ifp = THREAD_ARG(t);
+ ifp = EVENT_ARG(t);
ri = ifp->info;
zlog_debug("turn on %s", ifp->name);
/* Add interface wake up thread. */
- thread_add_timer(master, rip_interface_wakeup, ifp, 1,
- &ri->t_wakeup);
+ event_add_timer(master, rip_interface_wakeup, ifp, 1,
+ &ri->t_wakeup);
rip_connect_set(ifp, 1);
} else if (ri->running) {
/* Might as well clean up the route table as well
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "memory.h"
#include "prefix.h"
.cap_num_i = 0};
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
static struct frr_daemon_info ripd_di;
}
if (rinfo) {
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
listnode_delete(list, rinfo);
rip_info_free(rinfo);
}
#include "prefix.h"
#include "command.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "ripd/ripd.h"
static void rip_peer_free(struct rip_peer *peer)
{
- THREAD_OFF(peer->t_timeout);
+ EVENT_OFF(peer->t_timeout);
XFREE(MTYPE_RIP_PEER, peer);
}
}
/* RIP peer is timeout. */
-static void rip_peer_timeout(struct thread *t)
+static void rip_peer_timeout(struct event *t)
{
struct rip_peer *peer;
- peer = THREAD_ARG(t);
+ peer = EVENT_ARG(t);
listnode_delete(peer->rip->peer_list, peer);
rip_peer_free(peer);
}
peer = rip_peer_lookup(rip, addr);
if (peer) {
- THREAD_OFF(peer->t_timeout);
+ EVENT_OFF(peer->t_timeout);
} else {
peer = rip_peer_new();
peer->rip = rip;
}
/* Update timeout thread. */
- thread_add_timer(master, rip_peer_timeout, peer, RIP_PEER_TIMER_DEFAULT,
- &peer->t_timeout);
+ event_add_timer(master, rip_peer_timeout, peer, RIP_PEER_TIMER_DEFAULT,
+ &peer->t_timeout);
/* Last update time set. */
time(&peer->uptime);
{RIP2PEERRCVBADPACKETS, COUNTER, RONLY, rip2PeerTable, 3, {4, 1, 5}},
{RIP2PEERRCVBADROUTES, COUNTER, RONLY, rip2PeerTable, 3, {4, 1, 6}}};
-extern struct thread_master *master;
+extern struct event_loop *master;
static uint8_t *rip2Globals(struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len,
}
/* Register RIPv2-MIB. */
-static int rip_snmp_init(struct thread_master *master)
+static int rip_snmp_init(struct event_loop *master)
{
rip_ifaddr_table = route_table_init();
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = rip_zebra_read_route,
};
-void rip_zclient_init(struct thread_master *master)
+void rip_zclient_init(struct event_loop *master)
{
/* Set default value to the zebra client structure. */
zclient = zclient_new(master, &zclient_options_default, rip_handlers,
#include "command.h"
#include "prefix.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "log.h"
#include "stream.h"
/* Prototypes. */
static void rip_output_process(struct connected *, struct sockaddr_in *, int,
uint8_t);
-static void rip_triggered_update(struct thread *);
+static void rip_triggered_update(struct event *);
static int rip_update_jitter(unsigned long);
static void rip_distance_table_node_cleanup(struct route_table *table,
struct route_node *node);
}
/* RIP route garbage collect timer. */
-static void rip_garbage_collect(struct thread *t)
+static void rip_garbage_collect(struct event *t)
{
struct rip_info *rinfo;
struct route_node *rp;
- rinfo = THREAD_ARG(t);
+ rinfo = EVENT_ARG(t);
/* Off timeout timer. */
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
/* Get route_node pointer. */
rp = rinfo->rp;
if (tmp_rinfo == rinfo)
continue;
- THREAD_OFF(tmp_rinfo->t_timeout);
- THREAD_OFF(tmp_rinfo->t_garbage_collect);
+ EVENT_OFF(tmp_rinfo->t_timeout);
+ EVENT_OFF(tmp_rinfo->t_garbage_collect);
list_delete_node(list, node);
rip_info_free(tmp_rinfo);
}
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
memcpy(rinfo, rinfo_new, sizeof(struct rip_info));
if (rip_route_rte(rinfo)) {
struct route_node *rp = rinfo->rp;
struct list *list = (struct list *)rp->info;
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
if (listcount(list) > 1) {
/* Some other ECMP entries still exist. Just delete this entry.
*/
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_garbage_collect);
listnode_delete(list, rinfo);
if (rip_route_rte(rinfo)
&& CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
}
/* Timeout RIP routes. */
-static void rip_timeout(struct thread *t)
+static void rip_timeout(struct event *t)
{
- struct rip_info *rinfo = THREAD_ARG(t);
+ struct rip_info *rinfo = EVENT_ARG(t);
struct rip *rip = rip_info_get_instance(rinfo);
rip_ecmp_delete(rip, rinfo);
static void rip_timeout_update(struct rip *rip, struct rip_info *rinfo)
{
if (rinfo->metric != RIP_METRIC_INFINITY) {
- THREAD_OFF(rinfo->t_timeout);
- thread_add_timer(master, rip_timeout, rinfo, rip->timeout_time,
- &rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
+ event_add_timer(master, rip_timeout, rinfo, rip->timeout_time,
+ &rinfo->t_timeout);
}
}
assert(newinfo.metric
!= RIP_METRIC_INFINITY);
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
memcpy(rinfo, &newinfo,
sizeof(struct rip_info));
rip_timeout_update(rip, rinfo);
RIP_TIMER_ON(rinfo->t_garbage_collect,
rip_garbage_collect,
rip->garbage_time);
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
rinfo->flags |= RIP_RTF_CHANGED;
if (IS_RIP_DEBUG_EVENT)
}
/* First entry point of RIP packet. */
-static void rip_read(struct thread *t)
+static void rip_read(struct event *t)
{
- struct rip *rip = THREAD_ARG(t);
+ struct rip *rip = EVENT_ARG(t);
int sock;
int ret;
int rtenum;
struct prefix p;
/* Fetch socket then register myself. */
- sock = THREAD_FD(t);
+ sock = EVENT_FD(t);
/* Add myself to tne next event */
rip_event(rip, RIP_READ, sock);
}
/* RIP's periodical timer. */
-static void rip_update(struct thread *t)
+static void rip_update(struct event *t)
{
- struct rip *rip = THREAD_ARG(t);
+ struct rip *rip = EVENT_ARG(t);
if (IS_RIP_DEBUG_EVENT)
zlog_debug("update timer fire!");
/* Triggered updates may be suppressed if a regular update is due by
the time the triggered update would be sent. */
- THREAD_OFF(rip->t_triggered_interval);
+ EVENT_OFF(rip->t_triggered_interval);
rip->trigger = 0;
/* Register myself. */
}
/* Triggered update interval timer. */
-static void rip_triggered_interval(struct thread *t)
+static void rip_triggered_interval(struct event *t)
{
- struct rip *rip = THREAD_ARG(t);
+ struct rip *rip = EVENT_ARG(t);
if (rip->trigger) {
rip->trigger = 0;
}
/* Execute triggered update. */
-static void rip_triggered_update(struct thread *t)
+static void rip_triggered_update(struct event *t)
{
- struct rip *rip = THREAD_ARG(t);
+ struct rip *rip = EVENT_ARG(t);
int interval;
/* Cancel interval timer. */
- THREAD_OFF(rip->t_triggered_interval);
+ EVENT_OFF(rip->t_triggered_interval);
rip->trigger = 0;
/* Logging triggered update. */
update is triggered when the timer expires. */
interval = (frr_weak_random() % 5) + 1;
- thread_add_timer(master, rip_triggered_interval, rip, interval,
- &rip->t_triggered_interval);
+ event_add_timer(master, rip_triggered_interval, rip, interval,
+ &rip->t_triggered_interval);
}
/* Withdraw redistributed route. */
rinfo->metric = RIP_METRIC_INFINITY;
RIP_TIMER_ON(rinfo->t_garbage_collect, rip_garbage_collect,
rip->garbage_time);
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
rinfo->flags |= RIP_RTF_CHANGED;
if (IS_RIP_DEBUG_EVENT) {
switch (event) {
case RIP_READ:
- thread_add_read(master, rip_read, rip, sock, &rip->t_read);
+ event_add_read(master, rip_read, rip, sock, &rip->t_read);
break;
case RIP_UPDATE_EVENT:
- THREAD_OFF(rip->t_update);
+ EVENT_OFF(rip->t_update);
jitter = rip_update_jitter(rip->update_time);
- thread_add_timer(master, rip_update, rip,
- sock ? 2 : rip->update_time + jitter,
- &rip->t_update);
+ event_add_timer(master, rip_update, rip,
+ sock ? 2 : rip->update_time + jitter,
+ &rip->t_update);
break;
case RIP_TRIGGERED_UPDATE:
if (rip->t_triggered_interval)
rip->trigger = 1;
else
- thread_add_event(master, rip_triggered_update, rip, 0,
- &rip->t_triggered_update);
+ event_add_event(master, rip_triggered_update, rip, 0,
+ &rip->t_triggered_update);
break;
default:
break;
if (tmp_rinfo == rinfo)
continue;
- THREAD_OFF(tmp_rinfo->t_timeout);
- THREAD_OFF(tmp_rinfo->t_garbage_collect);
+ EVENT_OFF(tmp_rinfo->t_timeout);
+ EVENT_OFF(tmp_rinfo->t_garbage_collect);
list_delete_node(list, node);
rip_info_free(tmp_rinfo);
}
struct tm tm;
#define TIME_BUF 25
char timebuf[TIME_BUF];
- struct thread *thread;
+ struct event *thread;
if ((thread = rinfo->t_timeout) != NULL) {
- clock = thread_timer_remain_second(thread);
+ clock = event_timer_remain_second(thread);
gmtime_r(&clock, &tm);
strftime(timebuf, TIME_BUF, "%M:%S", &tm);
vty_out(vty, "%5s", timebuf);
} else if ((thread = rinfo->t_garbage_collect) != NULL) {
- clock = thread_timer_remain_second(thread);
+ clock = event_timer_remain_second(thread);
gmtime_r(&clock, &tm);
strftime(timebuf, TIME_BUF, "%M:%S", &tm);
vty_out(vty, "%5s", timebuf);
vty_out(vty, " Sending updates every %u seconds with +/-50%%,",
rip->update_time);
vty_out(vty, " next due in %lu seconds\n",
- thread_timer_remain_second(rip->t_update));
+ event_timer_remain_second(rip->t_update));
vty_out(vty, " Timeout after %u seconds,", rip->timeout_time);
vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time);
rip_zebra_ipv4_delete(rip, rp);
for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
rip_info_free(rinfo);
}
list_delete(&list);
rip_redistribute_disable(rip);
/* Cancel RIP related timers. */
- THREAD_OFF(rip->t_update);
- THREAD_OFF(rip->t_triggered_update);
- THREAD_OFF(rip->t_triggered_interval);
+ EVENT_OFF(rip->t_update);
+ EVENT_OFF(rip->t_triggered_update);
+ EVENT_OFF(rip->t_triggered_interval);
/* Cancel read thread. */
- THREAD_OFF(rip->t_read);
+ EVENT_OFF(rip->t_read);
/* Close RIP socket. */
close(rip->sock);
struct list *peer_list;
/* RIP threads. */
- struct thread *t_read;
+ struct event *t_read;
/* Update and garbage timer. */
- struct thread *t_update;
+ struct event *t_update;
/* Triggered update hack. */
int trigger;
- struct thread *t_triggered_update;
- struct thread *t_triggered_interval;
+ struct event *t_triggered_update;
+ struct event *t_triggered_interval;
/* RIP timer values. */
uint32_t update_time;
uint8_t flags;
/* Garbage collect timer. */
- struct thread *t_timeout;
- struct thread *t_garbage_collect;
+ struct event *t_timeout;
+ struct event *t_garbage_collect;
/* Route-map futures - this variables can be changed. */
struct in_addr nexthop_out;
struct route_map *routemap[RIP_FILTER_MAX];
/* Wake up thread. */
- struct thread *t_wakeup;
+ struct event *t_wakeup;
/* Interface statistics. */
int recv_badpackets;
int recv_badroutes;
/* Timeout thread. */
- struct thread *t_timeout;
+ struct event *t_timeout;
};
struct rip_distance {
};
/* Macro for timer turn on. */
-#define RIP_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
+#define RIP_TIMER_ON(T, F, V) event_add_timer(master, (F), rinfo, (V), &(T))
#define RIP_OFFSET_LIST_IN 0
#define RIP_OFFSET_LIST_OUT 1
extern void rip_route_map_init(void);
extern void rip_zebra_vrf_register(struct vrf *vrf);
extern void rip_zebra_vrf_deregister(struct vrf *vrf);
-extern void rip_zclient_init(struct thread_master *);
+extern void rip_zclient_init(struct event_loop *e);
extern void rip_zclient_stop(void);
extern int if_check_address(struct rip *rip, struct in_addr addr);
extern struct rip *rip_lookup_by_vrf_id(vrf_id_t vrf_id);
extern struct rip_instance_head rip_instances;
/* Master thread structure. */
-extern struct thread_master *master;
+extern struct event_loop *master;
DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc));
DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc));
#include "zclient.h"
#include "command.h"
#include "agg_table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "privs.h"
#include "vrf.h"
#include "lib_errors.h"
ri = ifp->info;
- THREAD_OFF(ri->t_wakeup);
+ EVENT_OFF(ri->t_wakeup);
ripng = ri->ripng;
ri->enable_interface = 0;
ri->running = 0;
- THREAD_OFF(ri->t_wakeup);
+ EVENT_OFF(ri->t_wakeup);
}
}
}
/* Wake up interface. */
-static void ripng_interface_wakeup(struct thread *t)
+static void ripng_interface_wakeup(struct event *t)
{
struct interface *ifp;
struct ripng_interface *ri;
/* Get interface. */
- ifp = THREAD_ARG(t);
+ ifp = EVENT_ARG(t);
ri = ifp->info;
zlog_info("RIPng INTERFACE ON %s", ifp->name);
/* Add interface wake up thread. */
- thread_add_timer(master, ripng_interface_wakeup, ifp, 1,
- &ri->t_wakeup);
+ event_add_timer(master, ripng_interface_wakeup, ifp, 1,
+ &ri->t_wakeup);
ripng_connect_set(ifp, 1);
} else {
#include "vty.h"
#include "command.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "log.h"
#include "prefix.h"
#include "if.h"
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
static struct frr_daemon_info ripngd_di;
}
if (rinfo) {
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
listnode_delete(list, rinfo);
ripng_info_free(rinfo);
}
#include "prefix.h"
#include "command.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "ripngd/ripngd.h"
static void ripng_peer_free(struct ripng_peer *peer)
{
- THREAD_OFF(peer->t_timeout);
+ EVENT_OFF(peer->t_timeout);
XFREE(MTYPE_RIPNG_PEER, peer);
}
/* RIPng peer is timeout.
* Garbage collector.
**/
-static void ripng_peer_timeout(struct thread *t)
+static void ripng_peer_timeout(struct event *t)
{
struct ripng_peer *peer;
- peer = THREAD_ARG(t);
+ peer = EVENT_ARG(t);
listnode_delete(peer->ripng->peer_list, peer);
ripng_peer_free(peer);
}
peer = ripng_peer_lookup(ripng, addr);
if (peer) {
- THREAD_OFF(peer->t_timeout);
+ EVENT_OFF(peer->t_timeout);
} else {
peer = ripng_peer_new();
peer->ripng = ripng;
}
/* Update timeout thread. */
- thread_add_timer(master, ripng_peer_timeout, peer,
- RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout);
+ event_add_timer(master, ripng_peer_timeout, peer,
+ RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout);
/* Last update time set. */
time(&peer->uptime);
};
/* Initialize zebra structure and it's commands. */
-void zebra_init(struct thread_master *master)
+void zebra_init(struct event_loop *master)
{
/* Allocate zebra structure. */
zclient = zclient_new(master, &zclient_options_default, ripng_handlers,
#include "prefix.h"
#include "filter.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "if.h"
#include "stream.h"
static void ripng_instance_enable(struct ripng *ripng, struct vrf *vrf,
int sock);
static void ripng_instance_disable(struct ripng *ripng);
-static void ripng_triggered_update(struct thread *);
+static void ripng_triggered_update(struct event *);
static void ripng_if_rmap_update(struct if_rmap_ctx *ctx,
struct if_rmap *if_rmap);
}
/* RIPng route garbage collect timer. */
-static void ripng_garbage_collect(struct thread *t)
+static void ripng_garbage_collect(struct event *t)
{
struct ripng_info *rinfo;
struct agg_node *rp;
- rinfo = THREAD_ARG(t);
+ rinfo = EVENT_ARG(t);
/* Off timeout timer. */
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
/* Get route_node pointer. */
rp = rinfo->rp;
/* Re-use the first entry, and delete the others. */
for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
if (tmp_rinfo != rinfo) {
- THREAD_OFF(tmp_rinfo->t_timeout);
- THREAD_OFF(tmp_rinfo->t_garbage_collect);
+ EVENT_OFF(tmp_rinfo->t_timeout);
+ EVENT_OFF(tmp_rinfo->t_garbage_collect);
list_delete_node(list, node);
ripng_info_free(tmp_rinfo);
}
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
memcpy(rinfo, rinfo_new, sizeof(struct ripng_info));
if (ripng_route_rte(rinfo)) {
struct agg_node *rp = rinfo->rp;
struct list *list = (struct list *)rp->info;
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
if (rinfo->metric != RIPNG_METRIC_INFINITY)
ripng_aggregate_decrement(rp, rinfo);
if (listcount(list) > 1) {
/* Some other ECMP entries still exist. Just delete this entry.
*/
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_garbage_collect);
listnode_delete(list, rinfo);
if (ripng_route_rte(rinfo)
&& CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB))
}
/* Timeout RIPng routes. */
-static void ripng_timeout(struct thread *t)
+static void ripng_timeout(struct event *t)
{
- struct ripng_info *rinfo = THREAD_ARG(t);
+ struct ripng_info *rinfo = EVENT_ARG(t);
struct ripng *ripng = ripng_info_get_instance(rinfo);
ripng_ecmp_delete(ripng, rinfo);
static void ripng_timeout_update(struct ripng *ripng, struct ripng_info *rinfo)
{
if (rinfo->metric != RIPNG_METRIC_INFINITY) {
- THREAD_OFF(rinfo->t_timeout);
- thread_add_timer(master, ripng_timeout, rinfo,
- ripng->timeout_time, &rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
+ event_add_timer(master, ripng_timeout, rinfo,
+ ripng->timeout_time, &rinfo->t_timeout);
}
}
* but
* highly recommended".
*/
- if (!ripng->ecmp && !same && rinfo->metric == rte->metric
- && rinfo->t_timeout
- && (thread_timer_remain_second(rinfo->t_timeout)
- < (ripng->timeout_time / 2))) {
+ if (!ripng->ecmp && !same && rinfo->metric == rte->metric &&
+ rinfo->t_timeout &&
+ (event_timer_remain_second(rinfo->t_timeout) <
+ (ripng->timeout_time / 2))) {
ripng_ecmp_replace(ripng, &newinfo);
}
/* Next, compare the metrics. If the datagram is from the same
router as the existing route, and the new metric is different
than the old one; or, if the new metric is lower than the old
one; do the following actions: */
- else if ((same && rinfo->metric != rte->metric)
- || rte->metric < rinfo->metric) {
+ else if ((same && rinfo->metric != rte->metric) ||
+ rte->metric < rinfo->metric) {
if (listcount(list) == 1) {
if (newinfo.metric != RIPNG_METRIC_INFINITY)
ripng_ecmp_replace(ripng, &newinfo);
RIPNG_TIMER_ON(rinfo->t_garbage_collect,
ripng_garbage_collect,
ripng->garbage_time);
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
/* Aggregate count decrement. */
ripng_aggregate_decrement(rp, rinfo);
RIPNG_TIMER_ON(rinfo->t_garbage_collect,
ripng_garbage_collect,
ripng->garbage_time);
- THREAD_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_timeout);
/* Aggregate count decrement. */
ripng_aggregate_decrement(rp, rinfo);
}
/* First entry point of reading RIPng packet. */
-static void ripng_read(struct thread *thread)
+static void ripng_read(struct event *thread)
{
- struct ripng *ripng = THREAD_ARG(thread);
+ struct ripng *ripng = EVENT_ARG(thread);
int len;
int sock;
struct sockaddr_in6 from;
/* Fetch thread data and set read pointer to empty for event
managing. `sock' sould be same as ripng->sock. */
- sock = THREAD_FD(thread);
+ sock = EVENT_FD(thread);
/* Add myself to the next event. */
ripng_event(ripng, RIPNG_READ, sock);
/* Regular update of RIPng route. Send all routing formation to RIPng
enabled interface. */
-static void ripng_update(struct thread *t)
+static void ripng_update(struct event *t)
{
- struct ripng *ripng = THREAD_ARG(t);
+ struct ripng *ripng = EVENT_ARG(t);
struct interface *ifp;
struct ripng_interface *ri;
/* Triggered updates may be suppressed if a regular update is due by
the time the triggered update would be sent. */
- THREAD_OFF(ripng->t_triggered_interval);
+ EVENT_OFF(ripng->t_triggered_interval);
ripng->trigger = 0;
/* Reset flush event. */
}
/* Triggered update interval timer. */
-static void ripng_triggered_interval(struct thread *t)
+static void ripng_triggered_interval(struct event *t)
{
- struct ripng *ripng = THREAD_ARG(t);
+ struct ripng *ripng = EVENT_ARG(t);
if (ripng->trigger) {
ripng->trigger = 0;
}
/* Execute triggered update. */
-void ripng_triggered_update(struct thread *t)
+void ripng_triggered_update(struct event *t)
{
- struct ripng *ripng = THREAD_ARG(t);
+ struct ripng *ripng = EVENT_ARG(t);
struct interface *ifp;
struct ripng_interface *ri;
int interval;
/* Cancel interval timer. */
- THREAD_OFF(ripng->t_triggered_interval);
+ EVENT_OFF(ripng->t_triggered_interval);
ripng->trigger = 0;
/* Logging triggered update. */
update is triggered when the timer expires. */
interval = (frr_weak_random() % 5) + 1;
- thread_add_timer(master, ripng_triggered_interval, ripng, interval,
- &ripng->t_triggered_interval);
+ event_add_timer(master, ripng_triggered_interval, ripng, interval,
+ &ripng->t_triggered_interval);
}
/* Write routing table entry to the stream and return next index of
switch (event) {
case RIPNG_READ:
- thread_add_read(master, ripng_read, ripng, sock,
- &ripng->t_read);
+ event_add_read(master, ripng_read, ripng, sock, &ripng->t_read);
break;
case RIPNG_UPDATE_EVENT:
- THREAD_OFF(ripng->t_update);
+ EVENT_OFF(ripng->t_update);
/* Update timer jitter. */
jitter = ripng_update_jitter(ripng->update_time);
- thread_add_timer(master, ripng_update, ripng,
- sock ? 2 : ripng->update_time + jitter,
- &ripng->t_update);
+ event_add_timer(master, ripng_update, ripng,
+ sock ? 2 : ripng->update_time + jitter,
+ &ripng->t_update);
break;
case RIPNG_TRIGGERED_UPDATE:
if (ripng->t_triggered_interval)
ripng->trigger = 1;
else
- thread_add_event(master, ripng_triggered_update, ripng,
- 0, &ripng->t_triggered_update);
+ event_add_event(master, ripng_triggered_update, ripng,
+ 0, &ripng->t_triggered_update);
break;
case RIPNG_ZEBRA:
case RIPNG_REQUEST_EVENT:
struct tm tm;
#define TIME_BUF 25
char timebuf[TIME_BUF];
- struct thread *thread;
+ struct event *thread;
if ((thread = rinfo->t_timeout) != NULL) {
- clock = thread_timer_remain_second(thread);
+ clock = event_timer_remain_second(thread);
gmtime_r(&clock, &tm);
strftime(timebuf, TIME_BUF, "%M:%S", &tm);
vty_out(vty, "%5s", timebuf);
} else if ((thread = rinfo->t_garbage_collect) != NULL) {
- clock = thread_timer_remain_second(thread);
+ clock = event_timer_remain_second(thread);
gmtime_r(&clock, &tm);
strftime(timebuf, TIME_BUF, "%M:%S", &tm);
vty_out(vty, "%5s", timebuf);
vty_out(vty, " Sending updates every %u seconds with +/-50%%,",
ripng->update_time);
vty_out(vty, " next due in %lu seconds\n",
- thread_timer_remain_second(ripng->t_update));
+ event_timer_remain_second(ripng->t_update));
vty_out(vty, " Timeout after %u seconds,", ripng->timeout_time);
vty_out(vty, " garbage collect after %u seconds\n",
ripng->garbage_time);
/* Drop all other entries, except the first one. */
for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo))
if (tmp_rinfo != rinfo) {
- THREAD_OFF(tmp_rinfo->t_timeout);
- THREAD_OFF(
- tmp_rinfo->t_garbage_collect);
+ EVENT_OFF(tmp_rinfo->t_timeout);
+ EVENT_OFF(tmp_rinfo->t_garbage_collect);
list_delete_node(list, node);
ripng_info_free(tmp_rinfo);
}
ripng_zebra_ipv6_delete(ripng, rp);
for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
- THREAD_OFF(rinfo->t_timeout);
- THREAD_OFF(rinfo->t_garbage_collect);
+ EVENT_OFF(rinfo->t_timeout);
+ EVENT_OFF(rinfo->t_garbage_collect);
ripng_info_free(rinfo);
}
list_delete(&list);
ripng_redistribute_disable(ripng);
/* Cancel the RIPng timers */
- THREAD_OFF(ripng->t_update);
- THREAD_OFF(ripng->t_triggered_update);
- THREAD_OFF(ripng->t_triggered_interval);
+ EVENT_OFF(ripng->t_update);
+ EVENT_OFF(ripng->t_triggered_update);
+ EVENT_OFF(ripng->t_triggered_interval);
/* Cancel the read thread */
- THREAD_OFF(ripng->t_read);
+ EVENT_OFF(ripng->t_read);
/* Close the RIPng socket */
if (ripng->sock >= 0) {
struct list *offset_list_master;
/* RIPng threads. */
- struct thread *t_read;
- struct thread *t_update;
+ struct event *t_read;
+ struct event *t_update;
/* Triggered update hack. */
int trigger;
- struct thread *t_triggered_update;
- struct thread *t_triggered_interval;
+ struct event *t_triggered_update;
+ struct event *t_triggered_interval;
/* RIPng ECMP flag */
bool ecmp;
uint8_t flags;
/* Garbage collect timer. */
- struct thread *t_timeout;
- struct thread *t_garbage_collect;
+ struct event *t_timeout;
+ struct event *t_garbage_collect;
/* Route-map features - this variables can be changed. */
struct in6_addr nexthop_out;
uint8_t default_only;
/* Wake up thread. */
- struct thread *t_wakeup;
+ struct event *t_wakeup;
/* Passive interface. */
int passive;
int recv_badroutes;
/* Timeout thread. */
- struct thread *t_timeout;
+ struct event *t_timeout;
};
/* All RIPng events. */
};
/* RIPng timer on/off macro. */
-#define RIPNG_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
+#define RIPNG_TIMER_ON(T, F, V) event_add_timer(master, (F), rinfo, (V), &(T))
#define RIPNG_OFFSET_LIST_IN 0
#define RIPNG_OFFSET_LIST_OUT 1
/* Extern variables. */
extern struct zebra_privs_t ripngd_privs;
-extern struct thread_master *master;
+extern struct event_loop *master;
extern struct ripng_instance_head ripng_instances;
/* Prototypes. */
extern void ripng_zebra_vrf_deregister(struct vrf *vrf);
extern void ripng_terminate(void);
/* zclient_init() is done by ripng_zebra.c:zebra_init() */
-extern void zebra_init(struct thread_master *);
+extern void zebra_init(struct event_loop *master);
extern void ripng_zebra_stop(void);
extern void ripng_redistribute_conf_update(struct ripng *ripng, int type);
extern void ripng_redistribute_conf_delete(struct ripng *ripng, int type);
#include "prefix.h"
#include "nexthop.h"
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vrf.h"
#include "zclient.h"
#include "frr_pthread.h"
static struct rusage lp_rusage;
static struct vty *lp_vty;
-extern struct thread_master *master;
+extern struct event_loop *master;
-static void logpump_done(struct thread *thread)
+static void logpump_done(struct event *thread)
{
double x;
getrusage(RUSAGE_SELF, &lp_rusage);
#endif
- thread_add_timer_msec(master, logpump_done, NULL, 0, NULL);
+ event_add_timer_msec(master, logpump_done, NULL, 0, NULL);
return NULL;
}
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "prefix.h"
#include "linklist.h"
#include "if.h"
struct option longopts[] = {{0}};
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/* SIGHUP handler. */
static void sighup(void)
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "network.h"
#include "prefix.h"
struct zclient *zclient = NULL;
/* For registering threads. */
-extern struct thread_master *master;
+extern struct event_loop *master;
/* Privs info */
extern struct zebra_privs_t sharp_privs;
zclient->session_id, info.type);
if (info.type == LINK_STATE_UPDATE) {
- lse = ls_stream2ted(sg.ted, s, false);
+ lse = ls_stream2ted(sg.ted, s, true);
if (lse) {
zlog_debug(" |- Got %s %s from Link State Database",
status2txt[lse->status],
bfd_sess_install(sn->bsp);
}
-void static_bfd_initialize(struct zclient *zc, struct thread_master *tm)
+void static_bfd_initialize(struct zclient *zc, struct event_loop *tm)
{
/* Initialize BFD integration library. */
bfd_protocol_integration_init(zc, tm);
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "log.h"
#include "memory.h"
struct option longopts[] = { { 0 } };
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
uintptr_t mgmt_lib_hndl;
extern void static_next_hop_bfd_multi_hop(struct static_nexthop *sn, bool mhop);
/** Call this function after zebra client initialization. */
-extern void static_bfd_initialize(struct zclient *zc, struct thread_master *tm);
+extern void static_bfd_initialize(struct zclient *zc, struct event_loop *tm);
extern void static_bfd_show(struct vty *vty, bool isjson);
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "network.h"
#include "prefix.h"
extern "C" {
#endif
-extern struct thread_master *master;
+extern struct event_loop *master;
extern void static_zebra_nht_register(struct static_nexthop *nh, bool reg);
/* need these to link in libbgp */
struct zebra_privs_t bgpd_privs = {};
-struct thread_master *master = NULL;
+struct event_loop *master = NULL;
static int failed = 0;
{
int i = 0;
qobj_init();
- bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE,
+ bgp_master_init(event_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE,
list_new());
master = bm->master;
bgp_option_set(BGP_OPT_NO_LISTEN);
/* need these to link in libbgp */
struct zebra_privs_t bgpd_privs = {};
-struct thread_master *master = NULL;
+struct event_loop *master = NULL;
static int failed = 0;
static int tty = 0;
term_bgp_debug_as4 = -1UL;
qobj_init();
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
/* need these to link in libbgp */
struct zebra_privs_t bgpd_privs = {};
-struct thread_master *master = NULL;
+struct event_loop *master = NULL;
static int failed = 0;
/* need these to link in libbgp */
struct zebra_privs_t bgpd_privs = {};
-struct thread_master *master = NULL;
+struct event_loop *master = NULL;
static int failed = 0;
static int tty = 0;
qobj_init();
cmd_init(0);
bgp_vty_init();
- master = thread_master_create("test mp attr");
+ master = event_master_create("test mp attr");
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
};
/* need these to link in libbgp */
-struct thread_master *master = NULL;
+struct event_loop *master = NULL;
extern struct zclient *zclient;
struct zebra_privs_t bgpd_privs = {
.user = NULL,
static int global_test_init(void)
{
qobj_init();
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
zclient = zclient_new(master, &zclient_options_default, NULL, 0);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL);
{
if (zclient != NULL)
zclient_free(zclient);
- thread_master_free(master);
+ event_master_free(master);
return 0;
}
/* need these to link in libbgp */
struct zebra_privs_t bgpd_privs = {};
-struct thread_master *master = NULL;
+struct event_loop *master = NULL;
static struct bgp *bgp;
static as_t asn = 100;
{
struct peer *peer;
int i, j;
- struct thread t;
+ struct event t;
qobj_init();
bgp_attr_init();
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
/* Required variables to link in libbgp */
struct zebra_privs_t bgpd_privs = {0};
-struct thread_master *master;
+struct event_loop *master;
enum test_state {
TEST_SUCCESS,
zprivs_preinit(&bgpd_privs);
zprivs_init(&bgpd_privs);
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
nb_init(master, NULL, 0, false);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
bgp_option_set(BGP_OPT_NO_LISTEN);
nb_terminate();
yang_terminate();
zprivs_terminate(&bgpd_privs);
- thread_master_free(master);
+ event_master_free(master);
master = NULL;
}
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
extern void test_init(void);
-struct thread_master *master;
+struct event_loop *master;
struct option longopts[] = {{"daemon", no_argument, NULL, 'd'},
{"config_file", required_argument, NULL, 'f'},
}
static int timer_count;
-static void test_timer(struct thread *thread)
+static void test_timer(struct event *thread)
{
- int *count = THREAD_ARG(thread);
+ int *count = EVENT_ARG(thread);
printf("run %d of timer\n", (*count)++);
- thread_add_timer(master, test_timer, count, 5, NULL);
+ event_add_timer(master, test_timer, count, 5, NULL);
}
static void test_timer_init(void)
{
- thread_add_timer(master, test_timer, &timer_count, 10, NULL);
+ event_add_timer(master, test_timer, &timer_count, 10, NULL);
}
static void test_vty_init(void)
int vty_port = 4000;
int daemon_mode = 0;
char *progname;
- struct thread thread;
+ struct event thread;
char *config_file = NULL;
/* Set umask before anything for security */
progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
/* master init. */
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
while (1) {
int opt;
test_init();
/* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* Not reached. */
exit(0);
#include "test_common.h"
-struct thread_master *master;
+struct event_loop *master;
struct zebra_privs_t isisd_privs;
int isis_sock_init(struct isis_circuit *circuit)
struct lspdb_head lspdb[]);
/* Global variables. */
-extern struct thread_master *master;
+extern struct event_loop *master;
extern struct zebra_privs_t isisd_privs;
extern struct isis_topology test_topologies[];
#include "memory.h"
#include "sbuf.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlvs.h"
#include <lib/version.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "log.h"
cmd_terminate();
vty_terminate();
yang_terminate();
- thread_master_free(master);
+ event_master_free(master);
log_memstats(stderr, "test-isis-spf");
if (!isexit)
{
char *p;
char *progname;
- struct thread thread;
+ struct event thread;
bool debug = false;
/* Set umask before anything for security */
}
/* master init. */
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
isis_master_init(master);
/* Library inits. */
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* Not reached. */
exit(0);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
#include "common_cli.h"
-struct thread_master *master;
+struct event_loop *master;
int dump_args(struct vty *vty, const char *descr, int argc,
struct cmd_token *argv[])
vty_terminate();
nb_terminate();
yang_terminate();
- thread_master_free(master);
+ event_master_free(master);
log_memstats(stderr, "testcli");
if (!isexit)
/* main routine. */
int main(int argc, char **argv)
{
- struct thread thread;
+ struct event thread;
size_t yangcount;
/* Set umask before anything for security */
umask(0027);
/* master init. */
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
zlog_aux_init("NONE: ", test_log_prio);
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* Not reached. */
exit(0);
/* functions provided by common cli
* (includes main())
*/
-extern struct thread_master *master;
+extern struct event_loop *master;
extern int test_log_prio;
extern struct cmd_node vty_node;
extern void test_init_cmd(void); /* provided in test-commands-defun.c */
-struct thread_master *master; /* dummy for libfrr*/
+struct event_loop *master; /* dummy for libfrr*/
static vector test_cmds;
static char test_buf[32768];
#include "lib/frr_pthread.h"
#include "lib/frratomic.h"
#include "lib/frrstr.h"
-#include "lib/getopt.h"
#include "lib/graph.h"
#include "lib/hash.h"
#include "lib/hook.h"
#include "lib/stream.h"
#include "lib/table.h"
#include "lib/termtable.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/typesafe.h"
#include "lib/typerb.h"
#include "lib/vector.h"
cfg->fd = fd;
cmd_hostname_set("TEST");
- cfg->master = thread_master_create("TEST");
+ cfg->master = event_master_create("TEST");
zlog_5424_apply_dst(cfg);
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
#include "log.h"
#include "northbound.h"
-static struct thread_master *master;
+static struct event_loop *master;
struct troute {
struct prefix_ipv4 prefix;
vty_terminate();
nb_terminate();
yang_terminate();
- thread_master_free(master);
+ event_master_free(master);
log_memstats(stderr, "test-nb-oper-data");
if (!isexit)
/* main routine. */
int main(int argc, char **argv)
{
- struct thread thread;
+ struct event thread;
unsigned int num_vrfs = 2;
unsigned int num_interfaces = 4;
unsigned int num_routes = 6;
umask(0027);
/* master init. */
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
zlog_aux_init("NONE: ", ZLOG_DISABLED);
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* Not reached. */
exit(0);
#include <zebra.h>
#include "lib/zlog.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/sigevent.h"
int main(int argc, char **argv)
{
int number = 10;
- struct thread_master *master;
+ struct event_loop *master;
zlog_aux_init("NONE: ", LOG_DEBUG);
assertf(number > 1, "(B) the number was %d", number);
/* set up SIGABRT handler */
- master = thread_master_create("test");
+ master = event_master_create("test");
signal_init(master, 0, NULL);
func_for_bt(number);
#include <lib_vty.h>
#include <buffer.h>
-struct thread_master *master;
+struct event_loop *master;
int main(int argc, char **argv)
{
#include "network.h"
#include "prng.h"
-struct thread_master *master;
+struct event_loop *master;
struct acc_vals {
int c0;
#include "libfrr.h"
#include "routing_nb.h"
#include "northbound_cli.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vrf.h"
#include "vty.h"
#include <grpcpp/security/credentials.h>
#include "grpc/frr-northbound.grpc.pb.h"
-DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
+DEFINE_HOOK(frr_late_init, (struct event_loop * tm), (tm));
DEFINE_KOOH(frr_fini, (), ());
struct vty *vty;
bool mpls_enabled;
-struct thread_master *master;
+struct event_loop *master;
struct zebra_privs_t static_privs = {0};
struct frrmod_runtime *grpc_module;
char binpath[2 * MAXPATHLEN + 1];
&frr_staticd_info, &frr_vrf_info,
};
-static void grpc_thread_stop(struct thread *thread);
+static void grpc_thread_stop(struct event *thread);
static void _err_print(const void *cookie, const char *errstr)
{
static_debug_init();
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
nb_init(master, staticd_yang_modules, array_size(staticd_yang_modules),
false);
cmd_terminate();
nb_terminate();
yang_terminate();
- thread_master_free(master);
+ event_master_free(master);
master = NULL;
}
// Signal FRR event loop to stop
test_debug("client: pthread: adding event to stop us");
- thread_add_event(master, grpc_thread_stop, NULL, 0, NULL);
+ event_add_event(master, grpc_thread_stop, NULL, 0, NULL);
test_debug("client: pthread: DONE (returning)");
return NULL;
}
-static void grpc_thread_start(struct thread *thread)
+static void grpc_thread_start(struct event *thread)
{
struct frr_pthread_attr client = {
.start = grpc_client_test_start,
frr_pthread_wait_running(pth);
}
-static void grpc_thread_stop(struct thread *thread)
+static void grpc_thread_stop(struct event *thread)
{
std::cout << __func__ << ": frr_pthread_stop_all" << std::endl;
frr_pthread_stop_all();
static_startup();
- thread_add_event(master, grpc_thread_start, NULL, 0, NULL);
+ event_add_event(master, grpc_thread_start, NULL, 0, NULL);
/* Event Loop */
- struct thread thread;
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ struct event thread;
+ while (event_fetch(master, &thread))
+ event_call(&thread);
return 0;
}
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
#include <zebra.h>
#include <math.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
#include "tests.h"
-extern struct thread_master *master;
+extern struct event_loop *master;
enum { ITERS_FIRST = 0,
ITERS_ERR = 100,
printf("%s did %d, x = %g\n", str, i, x);
}
-static void clear_something(struct thread *thread)
+static void clear_something(struct event *thread)
{
- struct work_state *ws = THREAD_ARG(thread);
+ struct work_state *ws = EVENT_ARG(thread);
/* this could be like iterating through 150k of route_table
* or worse, iterating through a list of peers, to bgp_stop them with
while (ws->i < ITERS_MAX) {
slow_func(ws->vty, ws->str, ws->i);
ws->i++;
- if (thread_should_yield(thread)) {
- thread_add_timer_msec(master, clear_something, ws, 0,
- NULL);
+ if (event_should_yield(thread)) {
+ event_add_timer_msec(master, clear_something, ws, 0,
+ NULL);
return;
}
}
ws->vty = vty;
ws->i = ITERS_FIRST;
- thread_add_timer_msec(master, clear_something, ws, 0, NULL);
+ event_add_timer_msec(master, clear_something, ws, 0, NULL);
return CMD_SUCCESS;
}
*/
#include <zebra.h>
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE, "heavy_wq_node");
DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE_STR, "heavy_wq_node->str");
-extern struct thread_master *master;
+extern struct event_loop *master;
static struct work_queue *heavy_wq;
struct heavy_wq_node {
* CVS
*/
-struct thread_master *master;
+struct event_loop *master;
#if 0 /* set to 1 to use system alloc directly */
#undef XMALLOC
#include "zebra/rib.h"
#include "prng.h"
-struct thread_master *master;
+struct event_loop *master;
static int verbose;
static void str_append(char **buf, const char *repr)
exit(status);
}
-struct thread_master *master;
+struct event_loop *master;
/* main routine. */
int main(int argc, char **argv)
{
#include "tests/lib/cli/common_cli.h"
-extern struct thread_master *master;
+extern struct event_loop *master;
static void resolver_result(struct resolver_query *resq, const char *errstr,
int numaddrs, union sockunion *addr)
struct frr_signal_t sigs[] = {};
-struct thread_master *master;
+struct event_loop *master;
void func1(int *arg);
void func3(void);
func2(6, buf);
}
-static void threadfunc(struct thread *thread)
+static void threadfunc(struct event *thread)
{
func3();
}
int main(void)
{
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
signal_init(master, array_size(sigs), sigs);
zlog_aux_init("NONE: ", LOG_DEBUG);
- thread_execute(master, threadfunc, 0, 0);
+ event_execute(master, threadfunc, 0, 0);
exit(0);
}
.handler = &sigusr2,
}};
-struct thread_master *master;
-struct thread t;
+struct event_loop *master;
+struct event t;
int main(void)
{
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
signal_init(master, array_size(sigs), sigs);
zlog_aux_init("NONE: ", LOG_DEBUG);
- while (thread_fetch(master, &t))
- thread_call(&t);
+ while (event_fetch(master, &t))
+ event_call(&t);
exit(0);
}
#define s6_addr32 __u6_addr.__u6_addr32
#endif /*s6_addr32*/
-struct thread_master *master;
+struct event_loop *master;
/* This structure is copied from lib/srcdest_table.c to which it is
* private as far as other parts of Quagga are concerned.
static void test_state_free(struct test_state *test)
{
route_table_finish(test->table);
- hash_clean(test->log, log_free);
- hash_free(test->log);
+ hash_clean_and_free(&test->log, log_free);
XFREE(MTYPE_TMP, test);
}
#include <zebra.h>
#include <stream.h>
-#include <thread.h>
+#include "frrevent.h"
#include "printfrr.h"
static unsigned long long ham = 0xdeadbeefdeadbeef;
-struct thread_master *master;
+struct event_loop *master;
static void print_stream(struct stream *s)
{
char *prefix_str;
} test_node_t;
-struct thread_master *master;
+struct event_loop *master;
/*
* add_node
#include "memory.h"
#include "prng.h"
-#include "thread.h"
+#include "frrevent.h"
#define SCHEDULE_TIMERS 800
#define REMOVE_TIMERS 200
#define TIMESTR_LEN strlen("4294967296.999999")
-struct thread_master *master;
+struct event_loop *master;
static size_t log_buf_len;
static size_t log_buf_pos;
static struct prng *prng;
-static struct thread **timers;
+static struct event **timers;
static int timers_pending;
exit_code = 0;
}
- thread_master_free(master);
+ event_master_free(master);
XFREE(MTYPE_TMP, log_buf);
XFREE(MTYPE_TMP, expected_buf);
prng_free(prng);
exit(exit_code);
}
-static void timer_func(struct thread *thread)
+static void timer_func(struct event *thread)
{
int rv;
int main(int argc, char **argv)
{
int i, j;
- struct thread t;
+ struct event t;
struct timeval **alarms;
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
log_buf_len = SCHEDULE_TIMERS * (TIMESTR_LEN + 1) + 1;
log_buf_pos = 0;
/* Schedule timers to expire in 0..5 seconds */
interval_msec = prng_rand(prng) % 5000;
arg = XMALLOC(MTYPE_TMP, TIMESTR_LEN + 1);
- thread_add_timer_msec(master, timer_func, arg, interval_msec,
- &timers[i]);
+ event_add_timer_msec(master, timer_func, arg, interval_msec,
+ &timers[i]);
ret = snprintf(arg, TIMESTR_LEN + 1, "%lld.%06lld",
(long long)timers[i]->u.sands.tv_sec,
(long long)timers[i]->u.sands.tv_usec);
continue;
XFREE(MTYPE_TMP, timers[index]->arg);
- thread_cancel(&timers[index]);
+ event_cancel(&timers[index]);
timers_pending--;
}
}
XFREE(MTYPE_TMP, alarms);
- while (thread_fetch(master, &t))
- thread_call(&t);
+ while (event_fetch(master, &t))
+ event_call(&t);
return 0;
}
#include <stdio.h>
#include <unistd.h>
-#include "thread.h"
+#include "frrevent.h"
#include "prng.h"
#define SCHEDULE_TIMERS 1000000
#define REMOVE_TIMERS 500000
-struct thread_master *master;
+struct event_loop *master;
-static void dummy_func(struct thread *thread)
+static void dummy_func(struct event *thread)
{
}
{
struct prng *prng;
int i;
- struct thread **timers;
+ struct event **timers;
struct timeval tv_start, tv_lap, tv_stop;
unsigned long t_schedule, t_remove;
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
prng = prng_new(0);
timers = calloc(SCHEDULE_TIMERS, sizeof(*timers));
/* create thread structures so they won't be allocated during the
* time measurement */
for (i = 0; i < SCHEDULE_TIMERS; i++) {
- thread_add_timer_msec(master, dummy_func, NULL, 0, &timers[i]);
+ event_add_timer_msec(master, dummy_func, NULL, 0, &timers[i]);
}
for (i = 0; i < SCHEDULE_TIMERS; i++)
- thread_cancel(&timers[i]);
+ event_cancel(&timers[i]);
monotime(&tv_start);
long interval_msec;
interval_msec = prng_rand(prng) % (100 * SCHEDULE_TIMERS);
- thread_add_timer_msec(master, dummy_func, NULL, interval_msec,
- &timers[i]);
+ event_add_timer_msec(master, dummy_func, NULL, interval_msec,
+ &timers[i]);
}
monotime(&tv_lap);
int index;
index = prng_rand(prng) % SCHEDULE_TIMERS;
- thread_cancel(&timers[index]);
+ event_cancel(&timers[index]);
}
monotime(&tv_stop);
fflush(stdout);
free(timers);
- thread_master_free(master);
+ event_master_free(master);
prng_free(prng);
return 0;
}
DEFINE_MTYPE_STATIC(LIB, TESTBUF, "zmq test buffer");
DEFINE_MTYPE_STATIC(LIB, ZMQMSG, "zmq message");
-static struct thread_master *master;
+static struct event_loop *master;
static void msg_buf_free(void *data, void *hint)
{
printf("server recv: %s\n", buf);
fflush(stdout);
- frrzmq_thread_add_write_msg(master, serverwritefn, NULL, msg_id,
- zmqsock, &cb);
+ frrzmq_event_add_write_msg(master, serverwritefn, NULL, msg_id, zmqsock,
+ &cb);
}
static void serverfn(void *arg, void *zmqsock)
frrzmq_thread_cancel(&cb, &cb->read);
frrzmq_thread_cancel(&cb, &cb->write);
- frrzmq_thread_add_read_part(master, serverpartfn, NULL, NULL, zmqsock,
- &cb);
+ frrzmq_event_add_read_part(master, serverpartfn, NULL, NULL, zmqsock,
+ &cb);
}
static void sigchld(void)
{
void *zmqsock;
char dummy = 0;
- struct thread t;
+ struct event t;
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
signal_init(master, array_size(sigs), sigs);
frrzmq_init();
exit(1);
}
- frrzmq_thread_add_read_msg(master, serverfn, NULL, NULL, zmqsock, &cb);
+ frrzmq_event_add_read_msg(master, serverfn, NULL, NULL, zmqsock, &cb);
write(syncfd, &dummy, sizeof(dummy));
- while (thread_fetch(master, &t))
- thread_call(&t);
+ while (event_fetch(master, &t))
+ event_call(&t);
zmq_close(zmqsock);
frrzmq_finish();
- thread_master_free(master);
+ event_master_free(master);
log_memstats_stderr("test");
}
#include "common.h"
-struct thread_master *master;
+struct event_loop *master;
struct zebra_privs_t ospfd_privs;
struct ospf_test_node *root, struct ospf *ospf);
/* Global variables. */
-extern struct thread_master *master;
+extern struct event_loop *master;
extern struct ospf_topology topo1;
extern struct ospf_topology topo2;
extern struct ospf_topology topo3;
#include <zebra.h>
#include "getopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include <lib/version.h>
#include "vty.h"
#include "command.h"
cmd_terminate();
vty_terminate();
- thread_master_free(master);
+ event_master_free(master);
if (!isexit)
exit(0);
{
char *p;
char *progname;
- struct thread thread;
+ struct event thread;
bool debug = false;
/* Set umask before anything for security */
}
/* master init. */
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
/* Library inits. */
cmd_init(1);
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ while (event_fetch(master, &thread))
+ event_call(&thread);
/* Not reached. */
exit(0);
log file ospf6d.log
!
-debug ospf6 lsa unknown
-debug ospf6 zebra
-debug ospf6 interface
-debug ospf6 neighbor
+!debug ospf6 lsa unknown
+!debug ospf6 zebra
+!debug ospf6 interface
+!debug ospf6 neighbor
!
interface r1-eth4
!
-debug bfd network
-debug bfd peer
-debug bfd zebra
+!debug bfd network
+!debug bfd peer
+!debug bfd zebra
!
bfd
profile slow-tx
-debug bfd network
-debug bfd peer
-debug bfd zebra
+!debug bfd network
+!debug bfd peer
+!debug bfd zebra
!
bfd
profile slow-tx
!
-debug bgp updates
+!debug bgp updates
!
router bgp 65010
no bgp ebgp-requires-policy
!
-debug bgp updates
+!debug bgp updates
!
router bgp 65020
no bgp ebgp-requires-policy
!
-debug bgp updates
-debug bgp vpn leak-from-vrf
-debug bgp vpn leak-to-vrf
-debug bgp nht
+!debug bgp updates
+!debug bgp vpn leak-from-vrf
+!debug bgp vpn leak-to-vrf
+!debug bgp nht
!
router bgp 65001
bgp router-id 10.10.10.10
!
-debug bgp updates
+!debug bgp updates
!
router bgp 65001
bgp router-id 10.10.10.101
!
-debug bgp updates
+!debug bgp updates
!
router bgp 65002
no bgp ebgp-requires-policy
-debug bgp neighbor-events
-debug bgp nht
-debug bgp updates in
-debug bgp updates out
+!debug bgp neighbor-events
+!debug bgp nht
+!debug bgp updates in
+!debug bgp updates out
!
router bgp 100
no bgp ebgp-requires-policy
-debug bgp neighbor-events
-debug bgp nht
-debug bgp updates in
-debug bgp updates out
+!debug bgp neighbor-events
+!debug bgp nht
+!debug bgp updates in
+!debug bgp updates out
!
router bgp 200
no bgp ebgp-requires-policy
-debug bgp neighbor-events
-debug bgp nht
-debug bgp updates in
-debug bgp updates out
+!debug bgp neighbor-events
+!debug bgp nht
+!debug bgp updates in
+!debug bgp updates out
!
router bgp 300
no bgp ebgp-requires-policy
-debug bgp neighbor-events
-debug bgp nht
-debug bgp updates in
-debug bgp updates out
+!debug bgp neighbor-events
+!debug bgp nht
+!debug bgp updates in
+!debug bgp updates out
!
router bgp 400
no bgp ebgp-requires-policy
!
-debug bgp neighbor
+!debug bgp neighbor
!
router bgp 65001
no bgp ebgp-requires-policy
host1 = tgen.gears["host1"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- pe2.vtysh_cmd("debug zebra vxlan")
- pe2.vtysh_cmd("debug zebra kernel")
+ #pe2.vtysh_cmd("debug zebra vxlan")
+ #pe2.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host1.run("ping -c1 10.10.1.1")
ip_learn_test(tgen, host1, pe1, pe2, "10.10.1.55")
host2 = tgen.gears["host2"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- pe1.vtysh_cmd("debug zebra vxlan")
- pe1.vtysh_cmd("debug zebra kernel")
+ #pe1.vtysh_cmd("debug zebra vxlan")
+ #pe1.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host2.run("ping -c1 10.10.1.3")
ip_learn_test(tgen, host2, pe2, pe1, "10.10.1.56")
host1 = tgen.gears["host1"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- pe2.vtysh_cmd("debug zebra vxlan")
- pe2.vtysh_cmd("debug zebra kernel")
+ #pe2.vtysh_cmd("debug zebra vxlan")
+ #pe2.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host1.run("ping -c1 10.10.1.1")
ip_learn_test(tgen, host1, pe1, pe2, "10.10.1.55")
host2 = tgen.gears["host2"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- pe1.vtysh_cmd("debug zebra vxlan")
- pe1.vtysh_cmd("debug zebra kernel")
+ #pe1.vtysh_cmd("debug zebra vxlan")
+ #pe1.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host2.run("ping -c1 10.10.1.3")
ip_learn_test(tgen, host2, pe2, pe1, "10.10.1.56")
r3 = tgen.gears["r3"]
r4 = tgen.gears["r4"]
- def _bgp_check_advertised_routes(prefix_num):
- output = json.loads(
- r3.vtysh_cmd(
- "show bgp ipv4 labeled-unicast neighbors 192.168.34.4 advertised-routes json"
- )
- )
+ def _bgp_check_received_routes(pfxcount):
+ output = json.loads(r4.vtysh_cmd("show bgp ipv4 labeled-unicast summary json"))
expected = {
- "advertisedRoutes": {
- "10.0.0.1/32": {
- "appliedStatusSymbols": {
- "*": True,
- ">": True,
- "=": True,
- }
+ "peers": {
+ "192.168.34.3": {
+ "pfxRcd": pfxcount,
+ "state": "Established",
}
- },
- "totalPrefixCounter": prefix_num,
+ }
}
return topotest.json_cmp(output, expected)
- test_func = functools.partial(_bgp_check_advertised_routes, 2)
+ test_func = functools.partial(_bgp_check_received_routes, 2)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert (
result is None
- ), "Failed to advertise labeled-unicast with addpath (multipath)"
-
- def _bgp_check_received_routes():
- output = json.loads(r4.vtysh_cmd("show bgp ipv4 labeled-unicast json"))
- expected = {
- "routes": {
- "10.0.0.1/32": [
- {
- "valid": True,
- "path": "65003 65001",
- },
- {
- "valid": True,
- "path": "65003 65002",
- },
- ]
- }
- }
- return topotest.json_cmp(output, expected)
-
- test_func = functools.partial(_bgp_check_received_routes)
- _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
- assert result is None, "Failed to receive labeled-unicast with addpath (multipath)"
+ ), "Failed to receive labeled-unicast with addpath (multipath=2)"
step("Enable BGP session for R5")
r3.vtysh_cmd(
"""
)
- test_func = functools.partial(_bgp_check_advertised_routes, 3)
+ test_func = functools.partial(_bgp_check_received_routes, 3)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert (
result is None
- ), "Failed to advertise labeled-unicast with addpath (multipath)"
+ ), "Failed to receive labeled-unicast with addpath (multipath=3)"
step("Disable BGP session for R5")
r3.vtysh_cmd(
"""
)
- test_func = functools.partial(_bgp_check_advertised_routes, 2)
+ test_func = functools.partial(_bgp_check_received_routes, 2)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert (
result is None
- ), "Failed to advertise labeled-unicast with addpath (multipath)"
+ ), "Failed to receive labeled-unicast with addpath (multipath=2)"
if __name__ == "__main__":
!
-debug bgp updates
+!debug bgp updates
!
router bgp 65002
no bgp ebgp-requires-policy
--- /dev/null
+!
+!debug bgp updates
+!debug bgp neighbor
+!
+bgp route-map delay-timer 5
+!
+router bgp 65001
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ neighbor 192.168.1.2 remote-as external
+ address-family ipv4 unicast
+ network 10.10.10.1/32
+ network 10.10.10.2/32
+ network 10.10.10.3/32
+ aggregate-address 10.10.10.0/24 summary-only
+ neighbor 192.168.1.2 unsuppress-map r2
+ exit-address-family
+!
+ip prefix-list r1 seq 5 permit 10.10.10.1/32
+ip prefix-list r1 seq 10 permit 10.10.10.2/32
+!
+route-map r2 permit 10
+ match ip address prefix-list r1
+exit
--- /dev/null
+!
+int r1-eth0
+ ip address 192.168.1.1/24
+!
--- /dev/null
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.1 remote-as external
+!
--- /dev/null
+!
+int r2-eth0
+ ip address 192.168.1.2/24
+!
--- /dev/null
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+# Copyright (c) 2023 by
+# Donatas Abraitis <donatas@opensourcerouting.org>
+#
+
+"""
+
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+pytestmark = pytest.mark.bgpd
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def setup_module(mod):
+ topodef = {"s1": ("r1", "r2")}
+ tgen = Topogen(topodef, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for i, (rname, router) in enumerate(router_list.items(), 1):
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_route_map_delay_timer():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ r1 = tgen.gears["r1"]
+ r2 = tgen.gears["r2"]
+
+ def _bgp_converge_1():
+ output = json.loads(
+ r1.vtysh_cmd(
+ "show bgp ipv4 unicast neighbor 192.168.1.2 advertised-routes json"
+ )
+ )
+ expected = {
+ "advertisedRoutes": {
+ "10.10.10.0/24": {},
+ "10.10.10.1/32": {},
+ "10.10.10.2/32": {},
+ "10.10.10.3/32": None,
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge_1)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "10.10.10.3/32 should not be advertised to r2"
+
+ # Set route-map delay-timer to max value and remove 10.10.10.2/32.
+ # After this, r1 MUST do not announce updates immediately, and wait
+ # 600 seconds before withdrawing 10.10.10.2/32.
+ r2.vtysh_cmd(
+ """
+ configure terminal
+ bgp route-map delay-timer 600
+ no ip prefix-list r1 seq 10 permit 10.10.10.2/32
+ """
+ )
+
+ def _bgp_converge_2():
+ output = json.loads(
+ r1.vtysh_cmd(
+ "show bgp ipv4 unicast neighbor 192.168.1.2 advertised-routes json"
+ )
+ )
+ expected = {
+ "advertisedRoutes": {
+ "10.10.10.0/24": {},
+ "10.10.10.1/32": {},
+ "10.10.10.2/32": None,
+ "10.10.10.3/32": None,
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ # We are checking `not None` here to wait count*wait time and if we have different
+ # results than expected, it means good - 10.10.10.2/32 wasn't withdrawn immediately.
+ test_func = functools.partial(_bgp_converge_2)
+ _, result = topotest.run_and_expect(test_func, not None, count=60, wait=0.5)
+ assert (
+ result is not None
+ ), "10.10.10.2/32 advertised, but should not be advertised to r2"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
!
-debug bgp updates
-debug bgp vpn leak-from-vrf
-debug bgp vpn leak-to-vrf
-debug bgp nht
-debug route-map
+!debug bgp updates
+!debug bgp vpn leak-from-vrf
+!debug bgp vpn leak-to-vrf
+!debug bgp nht
+!debug route-map
!
router bgp 65001
bgp router-id 10.10.10.10
--- /dev/null
+router bgp 65001
+ neighbor 192.168.2.1 remote-as external
--- /dev/null
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# April 03 2023, Trey Aspelund <taspelund@nvidia.com>
+#
+# Copyright (C) 2023 NVIDIA Corporation
+#
+# Test if the CLI parser for RT/SoO ecoms correctly
+# constrain user input to valid 4-byte ASN values.
+#
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.common_config import step
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+ tgen.add_router("pe1")
+
+
+def setup_module(mod):
+ tgen = Topogen(build_topo, mod.__name__)
+ tgen.start_topology()
+ pe1 = tgen.gears["pe1"]
+ pe1.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "pe1/bgpd.conf"))
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_route_origin_parser():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ pe1 = tgen.gears["pe1"]
+
+ def _invalid_soo_accepted():
+ pe1.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65001
+ address-family ipv4 unicast
+ neighbor 192.168.2.1 soo 4294967296:65
+ """
+ )
+ run_cfg = pe1.vtysh_cmd("show run")
+ return "soo" in run_cfg
+
+ def _max_soo_accepted():
+ pe1.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65001
+ address-family ipv4 unicast
+ neighbor 192.168.2.1 soo 4294967295:65
+ """
+ )
+ run_cfg = pe1.vtysh_cmd("show run")
+ return "soo 4294967295:65" in run_cfg
+
+ def _invalid_rt_accepted():
+ pe1.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65001
+ address-family ipv4 unicast
+ rt vpn both 4294967296:65
+ """
+ )
+ run_cfg = pe1.vtysh_cmd("show run")
+ return "rt vpn" in run_cfg
+
+ def _max_rt_accepted():
+ pe1.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65001
+ address-family ipv4 unicast
+ rt vpn both 4294967295:65
+ """
+ )
+ run_cfg = pe1.vtysh_cmd("show run")
+ return "rt vpn both 4294967295:65" in run_cfg
+
+ step(
+ "Configure invalid 4-byte value SoO (4294967296:65), this should not be accepted"
+ )
+ test_func = functools.partial(_invalid_soo_accepted)
+ _, result = topotest.run_and_expect(test_func, False, count=30, wait=0.5)
+ assert result is False, "invalid 4-byte value of SoO accepted"
+
+ step("Configure max 4-byte value SoO (4294967295:65), this should be accepted")
+ test_func = functools.partial(_max_soo_accepted)
+ _, result = topotest.run_and_expect(test_func, True, count=30, wait=0.5)
+ assert result is True, "max 4-byte value of SoO not accepted"
+
+ step(
+ "Configure invalid 4-byte value RT (4294967296:65), this should not be accepted"
+ )
+ test_func = functools.partial(_invalid_rt_accepted)
+ _, result = topotest.run_and_expect(test_func, False, count=30, wait=0.5)
+ assert result is False, "invalid 4-byte value of RT accepted"
+
+ step("Configure max 4-byte value RT (4294967295:65), this should be accepted")
+ test_func = functools.partial(_max_rt_accepted)
+ _, result = topotest.run_and_expect(test_func, True, count=30, wait=0.5)
+ assert result is True, "max 4-byte value of RT not accepted"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
!
-debug bgp updates
+!debug bgp updates
!
router bgp 65002
no bgp ebgp-requires-policy
log monitor notifications
log commands
!
-debug zebra packet
-debug zebra dplane
-debug zebra kernel
+!debug zebra packet
+!debug zebra dplane
+!debug zebra kernel
!
interface eth0
ipv6 address 2001::1/64
log monitor notifications
log commands
!
-debug zebra packet
-debug zebra dplane
-debug zebra kernel
+!debug zebra packet
+!debug zebra dplane
+!debug zebra kernel
!
interface eth0
ipv6 address 2001::2/64
log monitor notifications
log commands
!
-debug zebra packet
-debug zebra dplane
-debug zebra kernel
+!debug zebra packet
+!debug zebra dplane
+!debug zebra kernel
!
interface eth0
ipv6 address 2001::1/64
frr defaults traditional
!
-bgp send-extra-data zebra
+!bgp send-extra-data zebra
!
hostname r2
password zebra
log monitor notifications
log commands
!
-debug zebra packet
-debug zebra dplane
-debug zebra kernel
+!debug zebra packet
+!debug zebra dplane
+!debug zebra kernel
!
interface eth0
ipv6 address 2001::2/64
!
ip route 192.168.1.1/32 10.0.0.10
!
-debug bgp bestpath
-debug bgp nht
-debug bgp updates
-debug bgp update-groups
-debug bgp zebra
-debug zebra rib detail
+!debug bgp bestpath
+!debug bgp nht
+!debug bgp updates
+!debug bgp update-groups
+!debug bgp zebra
+!debug zebra rib detail
!
router bgp 2
address-family ipv4 uni
-debug bgp updates
-debug bgp bestpath 40.0.0.0/8
-debug bgp zebra
+!debug bgp updates
+!debug bgp bestpath 40.0.0.0/8
+!debug bgp zebra
!
router bgp 2
no bgp ebgp-requires-policy
neighbor 10.0.0.1 remote-as 1
neighbor 10.0.0.10 remote-as 3
address-family ipv4 uni
- network 60.0.0.0/24
\ No newline at end of file
+ network 60.0.0.0/24
assertmsg = '"r2" 192.168.1.1/32 route should be gone'
assert result is None, assertmsg
+def test_local_vs_non_local():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ r2 = tgen.gears["r2"]
+
+ output = json.loads(r2.vtysh_cmd("show bgp ipv4 uni 60.0.0.0/24 json"))
+ paths = output["paths"]
+ for i in range(len(paths)):
+ if "fibPending" in paths[i]:
+ assert(False), "Route 60.0.0.0/24 should not have fibPending"
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
--- /dev/null
+[exabgp.api]
+encoder = text
+highres = false
+respawn = false
+socket = ''
+
+[exabgp.bgp]
+openwait = 60
+
+[exabgp.cache]
+attributes = true
+nexthops = true
+
+[exabgp.daemon]
+daemonize = true
+pid = '/var/run/exabgp/exabgp.pid'
+user = 'exabgp'
+##daemonize = false
+
+[exabgp.log]
+all = false
+configuration = true
+daemon = true
+destination = '/var/log/exabgp.log'
+enable = true
+level = INFO
+message = false
+network = true
+packets = false
+parser = false
+processes = true
+reactor = true
+rib = false
+routes = false
+short = false
+timers = false
+
+[exabgp.pdb]
+enable = false
+
+[exabgp.profile]
+enable = false
+file = ''
+
+[exabgp.reactor]
+speed = 1.0
+
+[exabgp.tcp]
+acl = false
+bind = ''
+delay = 0
+once = false
+port = 179
--- /dev/null
+neighbor 10.0.0.1 {
+ router-id 10.0.0.2;
+ local-address 10.0.0.2;
+ local-as 65001;
+ peer-as 65534;
+ md5 test123;
+
+ static {
+ route 192.168.100.1/32 {
+ next-hop 10.0.0.2;
+ }
+ }
+}
--- /dev/null
+!
+!debug bgp neighbor
+!
+router bgp 65534 vrf public
+ bgp router-id 10.0.0.1
+ no bgp ebgp-requires-policy
+ neighbor 10.0.0.2 remote-as external
+ neighbor 10.0.0.2 timers 3 10
+ neighbor 10.0.0.2 timers connect 1
+ neighbor 10.0.0.2 password test123
+!
--- /dev/null
+!
+interface r1-eth0 vrf public
+ ip address 10.0.0.1/24
+!
+ip forwarding
+!
--- /dev/null
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+#
+# Copyright (c) 2023 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+
+"""
+Test if BGP MD5 basic authentication works per-VRF.
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+ r1 = tgen.add_router("r1")
+ peer1 = tgen.add_exabgp_peer("peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1")
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(r1)
+ switch.add_link(peer1)
+
+
+def setup_module(mod):
+ tgen = Topogen(build_topo, mod.__name__)
+ tgen.start_topology()
+
+ r1 = tgen.gears["r1"]
+ r1.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf"))
+ r1.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf"))
+ r1.start()
+
+ peer = tgen.gears["peer1"]
+ peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env"))
+
+ # VRF 'public'
+ r1.cmd_raises("ip link add public type vrf table 1001")
+ r1.cmd_raises("ip link set up dev public")
+ r1.cmd_raises("ip link set r1-eth0 master public")
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_vrf_md5_peering():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ def _bgp_converge():
+ output = json.loads(
+ tgen.gears["r1"].vtysh_cmd("show ip bgp vrf public neighbor 10.0.0.2 json")
+ )
+ expected = {
+ "10.0.0.2": {
+ "bgpState": "Established",
+ "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge)
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, "Can't peer with md5 per-VRF"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
hostname r5
log file ldpd.log
!
-debug mpls ldp zebra
-debug mpls ldp event
-debug mpls ldp errors
-debug mpls ldp sync
+!debug mpls ldp zebra
+!debug mpls ldp event
+!debug mpls ldp errors
+!debug mpls ldp sync
!
mpls ldp
router-id 3.3.3.3
-debug ospf6 lsa all
-debug ospf6 message all
-debug ospf6 route all
-debug ospf6 spf time
-debug ospf6 spf database
-debug ospf6 zebra send
-debug ospf6 zebra recv
-
-debug ospf6 lsa router
-debug ospf6 lsa router originate
-debug ospf6 lsa router examine
-debug ospf6 lsa router flooding
-debug ospf6 lsa as-external
-debug ospf6 lsa as-external originate
-debug ospf6 lsa as-external examine
-debug ospf6 lsa as-external flooding
-debug ospf6 lsa intra-prefix
-debug ospf6 lsa intra-prefix originate
-debug ospf6 lsa intra-prefix examine
-debug ospf6 lsa intra-prefix flooding
-debug ospf6 border-routers
-debug ospf6 zebra
-debug ospf6 interface
-debug ospf6 neighbor
-debug ospf6 flooding
-debug ospf6 gr helper
-debug ospf6 spf process
-debug ospf6 route intra-area
-debug ospf6 route inter-area
-debug ospf6 abr
-debug ospf6 asbr
-debug ospf6 nssa
+!debug ospf6 lsa all
+!debug ospf6 message all
+!debug ospf6 route all
+!debug ospf6 spf time
+!debug ospf6 spf database
+!debug ospf6 zebra send
+!debug ospf6 zebra recv
+!
+!debug ospf6 lsa router
+!debug ospf6 lsa router originate
+!debug ospf6 lsa router examine
+!debug ospf6 lsa router flooding
+!debug ospf6 lsa as-external
+!debug ospf6 lsa as-external originate
+!debug ospf6 lsa as-external examine
+!debug ospf6 lsa as-external flooding
+!debug ospf6 lsa intra-prefix
+!debug ospf6 lsa intra-prefix originate
+!debug ospf6 lsa intra-prefix examine
+!debug ospf6 lsa intra-prefix flooding
+!debug ospf6 border-routers
+!debug ospf6 zebra
+!debug ospf6 interface
+!debug ospf6 neighbor
+!debug ospf6 flooding
+!debug ospf6 gr helper
+!debug ospf6 spf process
+!debug ospf6 route intra-area
+!debug ospf6 route inter-area
+!debug ospf6 abr
+!debug ospf6 asbr
+!debug ospf6 nssa
!
interface r1-eth0
ipv6 ospf6 area 0
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
"ospf": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Change the summary address mask to lower match (ex - 16 to 8)")
ospf_summ_r1 = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step(
"Verify that external routes(static / connected) are summarised"
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Change the summary address mask to higher match (ex - 8 to 24)")
ospf_summ_r1 = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step(
"Verify that external routes(static / connected) are summarised"
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step(" Un configure one of the summary address.")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step(
"Configure route map and & rule to permit configured summary address,"
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
input_dict = {
SUMMARY["ipv4"][0]: {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step(
"Configure External Route summary in R0 to summarise 5"
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Delete the configured summary")
ospf_summ_r1 = {
step("Verify that summary lsa is withdrawn from R1 and deleted from R0.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Summary Route should not present in RIB"
+ "Error: Summary Route still present in RIB".format(tc_name)
)
step("show ip ospf summary should not have any summary address.")
}
dut = "r0"
result = verify_ospf_summary(tgen, topo, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Summary Route should not present in OSPF DB"
+ "Error: Summary still present in DB".format(tc_name)
+ )
dut = "r1"
step("All 5 routes are advertised after deletion of configured summary.")
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("configure the summary again and delete static routes .")
ospf_summ_r1 = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
input_dict = {
"r0": {
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Add back static routes.")
input_dict_static_rtes = {
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_static_rtes, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv4"][0]}]}}
dut = "r1"
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show configure summaries.")
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Configure new static route which is matching configured summary.")
input_dict_static_rtes = {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Shut one of the interface")
intf = topo["routers"]["r0"]["links"]["r3-link0"]["interface"]
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv4"][0]}]}}
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
ospf_summ_r1 = {
"r0": {
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB. \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
"ospf": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary")
ospf_summ_r1 = {
step("Verify that summary lsa is withdrawn from R1 and deleted from R0.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Summary Routes should not be present in RIB. \n"
+ "Error: Summary Route still present in RIB".format(tc_name)
)
step("show ip ospf summary should not have any summary address.")
result = verify_ospf_summary(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary still present in DB".format(tc_name)
step("Configure Min tag value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Configure Max Tag Value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step(
"Verify that boundary values tags are used for summary route"
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("configure new static route with different tag.")
input_dict_static_rtes_11 = {
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, tag="88888", expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tag="88888",
expected=False,
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step(
"Verify that boundary values tags are used for summary route"
result = verify_ospf_summary(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary address")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that summary address is flushed from neighbor.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Configure summary first & then configure matching static route.")
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
"ospf": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
step("Verify that summary lsa is withdrawn from R1 and deleted from R0.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB "
+ "Error: Summary Route still present in RIB".format(tc_name)
)
step("show ip ospf summary should not have any summary address.")
result = verify_ospf_summary(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary still present in DB".format(tc_name)
step("Configure Min tag value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Configure Max Tag Value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step(
"Verify that boundary values tags are used for summary route"
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("configure new static route with different tag.")
input_dict_static_rtes_11 = {
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, tag="88888", expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tag="88888",
expected=False,
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB.\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step(
"Verify that boundary values tags are used for summary route"
result = verify_ospf_summary(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary address")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that summary address is flushed from neighbor.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB \n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Configure summary first & then configure matching static route.")
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step(
"Configure External Route summary in R0 to summarise 5"
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB.\n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB."
+ "Error: Routes still present in RIB".format(tc_name)
+ )
- step("Verify that show ip ospf summary should show the " "configured summaries.")
+ step("Verify that show ip ospf summary should show the configured summaries.")
input_dict = {
SUMMARY["ipv4"][0]: {
"summaryAddress": SUMMARY["ipv4"][0],
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary")
ospf_summ_r1 = {
step("Verify that summary lsa is withdrawn from R1 and deleted from R0.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB. \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
- )
+ ), "Testcase {} : Failed. Error: Summary Route still present in RIB".format(tc_name)
step("show ip ospf summary should not have any summary address.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary still present in DB".format(tc_name)
step("Reconfigure summary with no advertise.")
ospf_summ_r1 = {
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB. \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB \n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
- step("Verify that show ip ospf summary should show the " "configured summaries.")
+ step("Verify that show ip ospf summary should show the configured summaries.")
input_dict = {
SUMMARY["ipv4"][0]: {
"summaryAddress": SUMMARY["ipv4"][0],
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step(
"Change summary address from no advertise to advertise "
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes is present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB"
+ "Error: Routes is present in RIB".format(tc_name)
+ )
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n \n Expected: Routes should not be present in OSPF RIB.\n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB.\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step(
"configure route map and add rule to permit configured static "
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
input_dict = {
SUMMARY["ipv4"][0]: {
step("Verify that advertised summary route is flushed from neighbor.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB\n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in RIB.\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Delete the configured route map.")
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
input_dict = {
SUMMARY["ipv4"][0]: {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Reconfigure the route map with denying configure summary address.")
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Redistribute static/connected routes without route map.")
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
input_dict = {
SUMMARY["ipv4"][0]: {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step(
"Configure rule to deny all the routes in route map and configure"
step("Verify that no summary route is originated.")
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict_summary, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB.\n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict_summary, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
routemaps = {
"r0": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Change route map rule for 1 of the routes to deny.")
# Create ip prefix list
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("add rule in route map to deny configured summary address.")
# Create ip prefix list
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
write_test_footer(tc_name)
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB.\n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB.\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Reload the FRR router")
# stop/start -> restart FRR router and verify
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB. \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("Kill OSPFd daemon on R0.")
kill_router_daemons(tgen, "r0", ["ospfd"])
step("Verify OSPF neighbors are up after bringing back ospfd in R0")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed \n Expected: Routes should not be present in OSPF RIB. \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
step("restart zebrad")
kill_router_daemons(tgen, "r0", ["zebra"])
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv4"], "next_hop": "blackhole"}]}
}
dut = "r1"
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
- assert (
- result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
- tc_name, result
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in OSPF RIB. \n Error: "
+ "Routes still present in OSPF RIB {}".format(tc_name, result)
)
result = verify_rib(
tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
)
- assert (
- result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ assert result is not True, (
+ "Testcase {} : Failed\n Expected: Routes should not be present in RIB.\n"
+ "Error: Routes still present in RIB".format(tc_name)
+ )
write_test_footer(tc_name)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r0 = {
"r0": {
"route is sent to R1."
)
- step(
- "Configure summary & redistribute static/connected route with " "metric type 2"
- )
+ step("Configure summary & redistribute static/connected route with metric type 2")
input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv4"][3]}]}}
dut = "r1"
result = verify_rib(tgen, "ipv4", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Learn type 7 lsa from neighbours")
result = verify_rib(tgen, "ipv4", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Routes is missing in RIB".format(tc_name)
ospf_summ_r0 = {
"r0": {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
step("Verify that already originated summary is intact.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed. Error: Summary missing in OSPF DB".format(tc_name)
dut = "r1"
aggr_timer = {"r1": {"ospf": {"aggr_timer": 6}}}
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
step("Verify that the neighbour is not FULL between R1 and R2.")
dut = "r1"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=10
)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
"show ip ospf neighbor cmd."
)
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r1"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=6
)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=10
)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
"show ip ospf neighbor cmd."
)
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r1"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=10
)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors after base config is done.")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r0"
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
step("Verify OSPF neighbors are up after bringing back ospfd in R0")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r1"
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is not True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors are up after bringing back ospfd in R1")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors after base config is done.")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors are up after restarting R0")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors are up after restarting R1")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors after base config is done.")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
step("Verify OSPF neighbors are up after bringing back ospfd in R0")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify OSPF neighbors are up after bringing back ospfd in R1")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
step("Verify that OSPF is up with 8 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
step("Verify that OSPF is up with 8 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
step("Verify that OSPF is up with 2 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
step("Verify that OSPF is up with 8 neighborship sessions.")
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r0"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Configure DR pririty 100 on R0 and clear ospf neighbors " "on all the routers."
- )
+ step("Configure DR pririty 100 on R0 and clear ospf neighbors on all the routers.")
input_dict = {
"r0": {
result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Configure DR pririty 150 on R0 and clear ospf neighbors " "on all the routers."
- )
+ step("Configure DR pririty 150 on R0 and clear ospf neighbors on all the routers.")
input_dict = {
"r0": {
result = verify_ospf_neighbor(tgen, topo, dut, lan=True, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r0: OSPF neighbors-hip is up \n Error: {}".format(
+ ), "Testcase {} : Failed \n r0: OSPF neighbors-hip is up \n Error: {}".format(
tc_name, result
)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
- step("Change area 1 as non nssa area (on the fly changing area" " type on DUT).")
+ step("Change area 1 as non nssa area (on the fly changing area type on DUT).")
for rtr in ["r1", "r2", "r3"]:
input_dict = {
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
redistribute_ospf(tgen, topo, "r0", "static", delete=True)
- step(
- "Create prefix-list in R0 to permit 10.0.20.1/32 prefix &" " deny 10.0.20.2/32"
- )
+ step("Create prefix-list in R0 to permit 10.0.20.1/32 prefix & deny 10.0.20.2/32")
# Create ip prefix list
pfx_list = {
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are present in fib \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are present in fib \n Error: {}".format(
tc_name, result
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
result = verify_ospf_rib(tgen, dut, input_dict, retry_timeout=4, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
result = verify_ospf_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format(
+ ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
tc_name, result
)
result = verify_prefix_lists(tgen, pfx_list)
assert (
result is not True
- ), "Testcase {} : Failed \n Prefix list not " "present. Error: {}".format(
+ ), "Testcase {} : Failed \n Prefix list not present. Error: {}".format(
tc_name, result
)
result = verify_prefix_lists(tgen, pfx_list)
assert (
result is not True
- ), "Testcase {} : Failed \n Prefix list not " "present. Error: {}".format(
+ ), "Testcase {} : Failed \n Prefix list not present. Error: {}".format(
tc_name, result
)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
step("Verify that OSPF neighbors are FULL.")
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify that OSPF neighbors are FULL.")
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify that OSPF neighbours are reset and forms new adjacencies.")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("Verify that OSPF neighbours are Full.")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
ospf_covergence
)
# Api call verify whether BGP is converged
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
reset_config_on_routers(tgen)
ospf_covergence = verify_ospf_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
dut = "r1"
result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step("modify dead interval from default value to r1" "dead interval timer on r2")
+ step("modify dead interval from default value to r1 dead interval timer on r2")
topo1 = {
"r0": {
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
- step("reconfigure the default dead interval timer value to " "default on r1 and r2")
+ step("reconfigure the default dead interval timer value to default on r1 and r2")
topo1 = {
"r0": {
"links": {
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
ospf_covergence
)
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Verify that timer value is deleted from intf & " "set to default value 40 sec."
- )
+ step("Verify that timer value is deleted from intf & set to default value 40 sec.")
input_dict = {"r1": {"links": {"r0": {"ospf": {"timerDeadSecs": 40}}}}}
dut = "r1"
result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict)
clear_ospf(tgen, "r0")
- step(
- "Verify that OSPF neighborship between R0 and R1 is stuck in Exstart" " State."
- )
+ step("Verify that OSPF neighborship between R0 and R1 is stuck in Exstart State.")
result = verify_ospf_neighbor(tgen, topo, expected=False)
assert result is not True, (
"Testcase {} : Failed \n OSPF nbrs are Full "
"instead of Exstart. Error: {}".format(tc_name, result)
)
- step(
- "Verify that configured MTU value is updated in the show ip " "ospf interface."
- )
+ step("Verify that configured MTU value is updated in the show ip ospf interface.")
dut = "r0"
input_dict = {"r0": {"links": {"r1": {"ospf": {"mtuBytes": 1200}}}}}
clear_ospf(tgen, "r0")
- step(
- "Verify that OSPF neighborship between R0 and R1 is stuck in Exstart" " State."
- )
+ step("Verify that OSPF neighborship between R0 and R1 is stuck in Exstart State.")
result = verify_ospf_neighbor(tgen, topo, expected=False)
assert result is not True, (
"Testcase {} : Failed \n OSPF nbrs are Full "
result = verify_ospf_neighbor(tgen, topo)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Configure ospf interface with jumbo MTU (9216)." "Reset ospf neighbors on R0."
- )
+ step("Configure ospf interface with jumbo MTU (9216). Reset ospf neighbors on R0.")
rtr0.run("ip link set {} mtu 9216".format(r0_r1_intf))
rtr1.run("ip link set {} mtu 9216".format(r1_r0_intf))
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
assert (
ospf_covergence is True
- ), "OSPF is not after reset config \n Error:" " {}".format(ospf_covergence)
+ ), "OSPF is not after reset config \n Error: {}".format(ospf_covergence)
- step("Verify that GR helper route is disabled by default to the in" "the DUT.")
+ step("Verify that GR helper route is disabled by default to the in the DUT.")
input_dict = {
"helperSupport": "Disabled",
"strictLsaCheck": "Enabled",
result = verify_ospf_gr_helper(tgen, topo, dut, input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step("Verify that DUT does not enter helper mode upon receiving the " "grace lsa.")
+ step("Verify that DUT does not enter helper mode upon receiving the grace lsa.")
# send grace lsa
scapy_send_raw_packet(tgen, topo, "r1", intf1, pkt)
result = verify_ospf_gr_helper(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed. DUT entered helper role " " \n Error: {}".format(
+ ), "Testcase {} : Failed. DUT entered helper role \n Error: {}".format(
tc_name, result
)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
step("Perform GR in RR.")
- step("Verify that DUT does enter helper mode upon receiving" " the grace lsa.")
+ step("Verify that DUT does enter helper mode upon receiving the grace lsa.")
input_dict = {"activeRestarterCnt": 1}
gracelsa_sent = False
repeat = 0
result = create_router_ospf(tgen, topo, ospf_gr_r0)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step("Verify that DUT does enter helper mode upon receiving" " the grace lsa.")
+ step("Verify that DUT does enter helper mode upon receiving the grace lsa.")
input_dict = {"activeRestarterCnt": 1}
gracelsa_sent = False
repeat = 0
result = create_router_ospf(tgen, topo, ospf_gr_r0)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step("Verify that GR helper router is disabled in the DUT for" " router id x.x.x.x")
+ step("Verify that GR helper router is disabled in the DUT for router id x.x.x.x")
input_dict = {"enabledRouterIds": [{"routerId": "1.1.1.1"}]}
dut = "r0"
result = verify_ospf_gr_helper(tgen, topo, dut, input_dict, expected=False)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
assert (
ospf_covergence is True
- ), "OSPF is not after reset config \n Error:" " {}".format(ospf_covergence)
+ ), "OSPF is not after reset config \n Error: {}".format(ospf_covergence)
ospf_gr_r0 = {
"r0": {"ospf": {"graceful-restart": {"helper enable": [], "opaque": True}}}
}
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
assert (
ospf_covergence is True
- ), "OSPF is not after reset config \n Error:" " {}".format(ospf_covergence)
- step(
- "Configure DR pririty 100 on R0 and clear ospf neighbors " "on all the routers."
- )
+ ), "OSPF is not after reset config \n Error: {}".format(ospf_covergence)
+ step("Configure DR pririty 100 on R0 and clear ospf neighbors on all the routers.")
input_dict = {
"r0": {
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
assert (
ospf_covergence is True
- ), "OSPF is not after reset config \n Error:" " {}".format(ospf_covergence)
- step(
- "Configure DR pririty 100 on R0 and clear ospf neighbors " "on all the routers."
- )
+ ), "OSPF is not after reset config \n Error: {}".format(ospf_covergence)
+ step("Configure DR pririty 100 on R0 and clear ospf neighbors on all the routers.")
input_dict = {
"r0": {
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
assert (
ospf_covergence is True
- ), "OSPF is not after reset config \n Error:" " {}".format(ospf_covergence)
+ ), "OSPF is not after reset config \n Error: {}".format(ospf_covergence)
ospf_gr_r0 = {
"r0": {"ospf": {"graceful-restart": {"helper enable": [], "opaque": True}}}
}
result = verify_ospf_gr_helper(tgen, topo, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed. DUT entered helper role " " \n Error: {}".format(
+ ), "Testcase {} : Failed. DUT entered helper role \n Error: {}".format(
tc_name, result
)
ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
assert (
ospf_covergence is True
- ), "OSPF is not after reset config \n Error:" " {}".format(ospf_covergence)
+ ), "OSPF is not after reset config \n Error: {}".format(ospf_covergence)
ospf_gr_r0 = {
"r0": {"ospf": {"graceful-restart": {"helper enable": [], "opaque": True}}}
}
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step(
"Configure External Route summary in R0 to summarise 5"
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv6"], "next_hop": "blackhole"}]}
}
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step("Delete the configured summary")
ospf_summ_r1 = {
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
- )
+ ), "Testcase {} : Failed Error: Summary Route still present in RIB".format(tc_name)
step("show ip ospf summary should not have any summary address.")
input_dict = {
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary still present in DB".format(tc_name)
dut = "r1"
step("All 5 routes are advertised after deletion of configured summary.")
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("configure the summary again and delete static routes .")
ospf_summ_r1 = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
input_dict = {
"r0": {
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step("Add back static routes.")
input_dict_static_rtes = {
result = verify_ospf6_rib(tgen, dut, input_dict_static_rtes, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv6"][0]}]}}
dut = "r1"
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show configure summaries.")
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Configure new static route which is matching configured summary.")
input_dict_static_rtes = {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Shut one of the interface")
intf = topo["routers"]["r0"]["links"]["r3-link0"]["interface"]
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv6"][0]}]}}
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
ospf_summ_r1 = {
"r0": {
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
"ospf6": {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Change the summary address mask to lower match (ex - 16 to 8)")
ospf_summ_r1 = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step(
"Verify that external routes(static / connected) are summarised"
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Change the summary address mask to higher match (ex - 8 to 24)")
ospf_summ_r1 = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step(
"Verify that external routes(static / connected) are summarised"
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step(" Un configure one of the summary address.")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
"ospf6": {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary")
ospf_summ_r1 = {
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
- )
+ ), "Testcase {} : Failed Error: Summary Route still present in RIB".format(tc_name)
step("show ip ospf summary should not have any summary address.")
input_dict = {
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary still present in DB".format(tc_name)
step("Configure Min tag value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Configure Max Tag Value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step(
"Verify that boundary values tags are used for summary route"
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("configure new static route with different tag.")
input_dict_static_rtes_11 = {
)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step(
"Verify that boundary values tags are used for summary route"
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary address")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that summary address is flushed from neighbor.")
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step("Configure summary first & then configure matching static route.")
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
"ospf6": {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
- )
+ ), "Testcase {} : Failed Error: Summary Route still present in RIB".format(tc_name)
step("show ip ospf summary should not have any summary address.")
input_dict = {
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary still present in DB".format(tc_name)
step("Configure Min tag value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries with tag.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Configure Max Tag Value")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step(
"Verify that boundary values tags are used for summary route"
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("configure new static route with different tag.")
input_dict_static_rtes_11 = {
)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step(
"Verify that boundary values tags are used for summary route"
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary address")
ospf_summ_r1 = {
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that summary address is flushed from neighbor.")
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step("Configure summary first & then configure matching static route.")
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step(
"Configure External Route summary in R0 to summarise 5"
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
- step("Verify that show ip ospf summary should show the " "configured summaries.")
+ step("Verify that show ip ospf summary should show the configured summaries.")
input_dict = {
SUMMARY["ipv6"][0]: {
"summaryAddress": SUMMARY["ipv6"][0],
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Delete the configured summary")
ospf_summ_r1 = {
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
- tc_name
- )
+ ), "Testcase {} : Failed Error: Summary Route still present in RIB".format(tc_name)
step("show ip ospf summary should not have any summary address.")
input_dict = {
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary still present in DB".format(tc_name)
step("Reconfigure summary with no advertise.")
ospf_summ_r1 = {
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
- step("Verify that show ip ospf summary should show the " "configured summaries.")
+ step("Verify that show ip ospf summary should show the configured summaries.")
input_dict = {
SUMMARY["ipv6"][0]: {
"summaryAddress": SUMMARY["ipv6"][0],
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step(
"Change summary address from no advertise to advertise "
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
output = tgen.gears["r0"].vtysh_cmd(
"show ipv6 ospf6 database as-external json", isjson=True
)
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes is present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is present in RIB".format(tc_name)
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv6"], "next_hop": "blackhole"}]}
}
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step(
"Configure route map and & rule to permit configured summary address,"
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
input_dict = {
SUMMARY["ipv6"][0]: {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Configure metric type as 1 in route map.")
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Un configure metric type from route map.")
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
step("Change rule from permit to deny in prefix list.")
pfx_list = {
result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
write_test_footer(tc_name)
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
write_test_footer(tc_name)
result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
- step(
- "Configure External Route summary in R0 to summarise 5" " routes to one route."
- )
+ step("Configure External Route summary in R0 to summarise 5 routes to one route.")
ospf_summ_r1 = {
"r0": {
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv6"], "next_hop": "blackhole"}]}
}
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
step("Reload the FRR router")
# stop/start -> restart FRR router and verify
result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
assert (
result is True
- ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes is missing in RIB".format(tc_name)
step("Verify that show ip ospf summary should show the summaries.")
input_dict = {
result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
assert (
result is True
- ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+ ), "Testcase {} : Failed Error: Summary missing in OSPF DB".format(tc_name)
- step("Verify that originally advertised routes are withdraw from there" " peer.")
+ step("Verify that originally advertised routes are withdraw from there peer.")
input_dict = {
"r0": {"static_routes": [{"network": NETWORK["ipv6"], "next_hop": "blackhole"}]}
}
result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+ ), "Testcase {} : Failed \n Error: Routes still present in OSPF RIB {}".format(
tc_name, result
)
)
assert (
result is not True
- ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+ ), "Testcase {} : Failed Error: Routes still present in RIB".format(tc_name)
write_test_footer(tc_name)
pytest.skip(tgen.errors)
ospf6_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf6_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=5
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
"show ip ospf6 neighbor cmd."
)
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=5
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
"show ip ospf6 neighbor cmd."
)
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=5
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
"show ip ospf6 neighbor cmd."
)
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=5
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
"show ip ospf6 neighbor cmd."
)
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
ospf6_covergence = verify_ospf6_neighbor(
tgen, topo, dut=dut, expected=False, retry_timeout=3
)
- assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
dut = "r2"
ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format(
+ assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format(
tc_name, ospf6_covergence
)
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
step("Verify that OSPF is up with 8 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
step("Verify that OSPF is up with 8 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
step("Verify that OSPF is up with 2 neighborship sessions.")
dut = "r1"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf6_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
step("Verify that OSPF is up with 8 neighborship sessions.")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
dut = "r0"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
dut = "r2"
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, lan=True)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
result = verify_ospf6_neighbor(tgen, topo)
- assert result is True, "setup_module: Failed \n Error:" " {}".format(result)
+ assert result is True, "setup_module: Failed \n Error: {}".format(result)
logger.info("Running setup_module() done")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
result = verify_ospf6_neighbor(tgen, topo, dut="r2", expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Nbrs are not down" "Error: {}".format(tc_name, result)
+ ), "Testcase {} : Failed \n Nbrs are not down Error: {}".format(tc_name, result)
step("Now configure area 0 on interface of r1 connecting to r2.")
result = verify_ospf6_neighbor(tgen, topo, dut="r2", expected=False)
assert (
result is not True
- ), "Testcase {} : Failed \n Nbrs are not down" "Error: {}".format(tc_name, result)
+ ), "Testcase {} : Failed \n Nbrs are not down Error: {}".format(tc_name, result)
step("Now configure area 2 on interface of r1 connecting to r2.")
result = verify_ospf6_neighbor(tgen, topo)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step("Change area 1 as non nssa area (on the fly changing area" " type on DUT).")
+ step("Change area 1 as non nssa area (on the fly changing area type on DUT).")
for rtr in ["r1", "r2", "r3"]:
input_dict = {
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
result = create_router_ospf(tgen, topo, ospf_red_r1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Create prefix-list in R0 to permit 10.0.20.1/32 prefix &" " deny 10.0.20.2/32"
- )
+ step("Create prefix-list in R0 to permit 10.0.20.1/32 prefix & deny 10.0.20.2/32")
# Create ip prefix list
pfx_list = {
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
result = verify_prefix_lists(tgen, pfx_list)
assert (
result is not True
- ), "Testcase {} : Failed \n Prefix list not " "present. Error: {}".format(
+ ), "Testcase {} : Failed \n Prefix list not present. Error: {}".format(
tc_name, result
)
result = verify_prefix_lists(tgen, pfx_list)
assert (
result is not True
- ), "Testcase {} : Failed \n Prefix list not " "present. Error: {}".format(
+ ), "Testcase {} : Failed \n Prefix list not present. Error: {}".format(
tc_name, result
)
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
step("Verify that OSPF neighbors are FULL.")
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
step("Verify that OSPF neighbours are reset and forms new adjacencies.")
# Api call verify whether OSPF is converged
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
pytest.skip(tgen.errors)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "setup_module :Failed \n Error: {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
ospf_covergence
)
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Verify that timer value is deleted from intf & " "set to default value 40 sec."
- )
+ step("Verify that timer value is deleted from intf & set to default value 40 sec.")
input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigHello": 10}}}}}
dut = "r1"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step("modify dead interval from default value to r1" "dead interval timer on r2")
+ step("modify dead interval from default value to r1 dead interval timer on r2")
topo1 = {
"r0": {
# reconfiguring deleted ospf process by resetting the configs.
reset_config_on_routers(tgen)
- step("reconfigure the default dead interval timer value to " "default on r1 and r2")
+ step("reconfigure the default dead interval timer value to default on r1 and r2")
topo1 = {
"r0": {
"links": {
result = create_interfaces_cfg(tgen, topo1)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Verify that timer value is deleted from intf & " "set to default value 40 sec."
- )
+ step("Verify that timer value is deleted from intf & set to default value 40 sec.")
input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigDead": 40}}}}}
dut = "r1"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
clear_ospf(tgen, "r0", ospf="ospf6")
clear_ospf(tgen, "r1", ospf="ospf6")
- step(
- "Verify that OSPF neighborship between R0 and R1 is stuck in Exstart" " State."
- )
+ step("Verify that OSPF neighborship between R0 and R1 is stuck in Exstart State.")
result = verify_ospf6_neighbor(tgen, topo, expected=False)
assert result is not True, (
"Testcase {} : Failed \n OSPF nbrs are Full "
"instead of Exstart. Error: {}".format(tc_name, result)
)
- step(
- "Verify that configured MTU value is updated in the show ip " "ospf interface."
- )
+ step("Verify that configured MTU value is updated in the show ip ospf interface.")
dut = "r0"
input_dict = {"r0": {"links": {"r1": {"ospf6": {"interfaceMtu": 1400}}}}}
clear_ospf(tgen, "r0", ospf="ospf6")
- step(
- "Verify that OSPF neighborship between R0 and R1 is stuck in Exstart" " State."
- )
+ step("Verify that OSPF neighborship between R0 and R1 is stuck in Exstart State.")
result = verify_ospf6_neighbor(tgen, topo, expected=False)
assert result is not True, (
"Testcase {} : Failed \n OSPF nbrs are Full "
result = verify_ospf6_neighbor(tgen, topo)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
- step(
- "Configure ospf interface with jumbo MTU (9216)." "Reset ospf neighbors on R0."
- )
+ step("Configure ospf interface with jumbo MTU (9216). Reset ospf neighbors on R0.")
rtr0.run("ifconfig {} mtu 9216".format(r0_r1_intf))
rtr1.run("ifconfig {} mtu 9216".format(r1_r0_intf))
result = create_debug_log_config(tgen, input_dict)
- # Code coverage steps #Do Not upstream
- input_dict_config = {
- "r1": {
- "raw_config": [
- "end",
- "debug ospf6 event",
- "debug ospf6 gr helper",
- "debug ospf6 ism events",
- "debug ospf6 ism status",
- "debug ospf6 ism timers",
- "debug ospf6 nsm events",
- "debug ospf6 nsm status",
- "debug ospf6 nsm timers ",
- "debug ospf6 nssa",
- "debug ospf6 lsa aggregate",
- "debug ospf6 lsa flooding ",
- "debug ospf6 lsa generate",
- "debug ospf6 lsa install ",
- "debug ospf6 lsa refresh",
- "debug ospf6 packet all detail",
- "debug ospf6 packet all recv",
- "debug ospf6 packet all send",
- "debug ospf6 packet dd detail",
- "debug ospf6 packet dd recv",
- "debug ospf6 packet dd send ",
- "debug ospf6 packet hello detail",
- "debug ospf6 packet hello recv",
- "debug ospf6 packet hello send",
- "debug ospf6 packet ls-ack detail",
- "debug ospf6 packet ls-ack recv",
- "debug ospf6 packet ls-ack send",
- "debug ospf6 packet ls-request detail",
- "debug ospf6 packet ls-request recv",
- "debug ospf6 packet ls-request send",
- "debug ospf6 packet ls-update detail",
- "debug ospf6 packet ls-update recv",
- "debug ospf6 packet ls-update send",
- "debug ospf6 sr",
- "debug ospf6 te ",
- "debug ospf6 zebra interface",
- "debug ospf6 zebra redistribute",
- ]
- }
- }
-
- apply_raw_config(tgen, input_dict_config)
-
for rtr in topo["routers"]:
clear_ospf(tgen, rtr, ospf="ospf6")
clear_ospf(tgen, rtr, ospf="ospf6")
ospf_covergence = verify_ospf6_neighbor(tgen, topo1)
- assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error: {}".format(
ospf_covergence
)
assert result is True, "Testcase : Failed \n Error: {}".format(result)
ospf_covergence = verify_ospf6_neighbor(tgen, topo, expected=False)
- assert (
- ospf_covergence is not True
- ), "OSPF NBRs are up.Failed \n Error:" " {}".format(ospf_covergence)
+ assert ospf_covergence is not True, "OSPF NBRs are up.Failed \n Error: {}".format(
+ ospf_covergence
+ )
topo1 = {}
topo1 = deepcopy(topo)
topo1["routers"]["r3"]["ospf6"]["router_id"] = "1.1.1.4"
ospf_covergence = verify_ospf6_neighbor(tgen, topo1)
- assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error: {}".format(
ospf_covergence
)
reset_config_on_routers(tgen)
ospf_covergence = verify_ospf6_neighbor(tgen, topo)
- assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error:" " {}".format(
+ assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error: {}".format(
ospf_covergence
)
{
#define thread_prefix "_"
static const char *const names[] = {
- thread_prefix "thread_add_read_write",
- thread_prefix "thread_add_timer",
- thread_prefix "thread_add_timer_msec",
- thread_prefix "thread_add_timer_tv",
- thread_prefix "thread_add_event",
- thread_prefix "thread_execute",
+ thread_prefix "event_add_read_write",
+ thread_prefix "event_add_timer",
+ thread_prefix "event_add_timer_msec",
+ thread_prefix "event_add_timer_tv",
+ thread_prefix "event_add_event",
+ thread_prefix "event_execute",
};
size_t i;
D_PATH="@CFG_SBIN@" # /usr/lib/frr
C_PATH="@CFG_SYSCONF@" # /etc/frr
V_PATH="@CFG_STATE@" # /var/run/frr
+B_PATH="@CFG_BIN@"
VTYSH="@vtysh_bin@" # /usr/bin/vtysh
FRR_USER="@enable_user@" # frr
FRR_GROUP="@enable_group@" # frr
NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}"
[ ! -r $NEW_CONFIG_FILE ] && echo "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1
echo "Applying only incremental changes to running configuration from frr.conf"
- "$RELOAD_SCRIPT" --reload --bindir "$D_PATH" --confdir "$C_PATH" --rundir "$V_PATH" "$C_PATH/frr.conf"
+ "$RELOAD_SCRIPT" --reload --bindir "$B_PATH" --confdir "$C_PATH" --rundir "$V_PATH" "$C_PATH/frr.conf"
exit $?
;;
D_PATH="@CFG_SBIN@" # /usr/lib/frr
C_PATH="@CFG_SYSCONF@${suffix}" # /etc/frr
V_PATH="@CFG_STATE@${suffix}" # /var/run/frr
+B_PATH="@CFG_BIN@"
VTYSH="@vtysh_bin@" # /usr/bin/vtysh
FRR_USER="@enable_user@" # frr
FRR_GROUP="@enable_group@" # frr
NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}"
[ ! -r $NEW_CONFIG_FILE ] && log_failure_msg "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1
- "$RELOAD_SCRIPT" --reload --bindir "$D_PATH" --confdir "$C_PATH" --rundir "$V_PATH" "$NEW_CONFIG_FILE" `echo $nsopt`
+ "$RELOAD_SCRIPT" --reload --bindir "$B_PATH" --confdir "$C_PATH" --rundir "$V_PATH" "$NEW_CONFIG_FILE" `echo $nsopt`
exit $?
;;
/* Forward decls */
static void vrrp_change_state(struct vrrp_router *r, int to);
-static void vrrp_adver_timer_expire(struct thread *thread);
-static void vrrp_master_down_timer_expire(struct thread *thread);
+static void vrrp_adver_timer_expire(struct event *thread);
+static void vrrp_master_down_timer_expire(struct event *thread);
/*
* Finds the first connected address of the appropriate family on a VRRP
if (pkt->hdr.priority == 0) {
vrrp_send_advertisement(r);
- THREAD_OFF(r->t_adver_timer);
- thread_add_timer_msec(
- master, vrrp_adver_timer_expire, r,
- r->vr->advertisement_interval * CS2MS,
- &r->t_adver_timer);
+ EVENT_OFF(r->t_adver_timer);
+ event_add_timer_msec(master, vrrp_adver_timer_expire, r,
+ r->vr->advertisement_interval *
+ CS2MS,
+ &r->t_adver_timer);
} else if (pkt->hdr.priority > r->priority
|| ((pkt->hdr.priority == r->priority)
&& addrcmp > 0)) {
"Received advertisement from %s w/ priority %hhu; switching to Backup",
r->vr->vrid, family2str(r->family), sipstr,
pkt->hdr.priority);
- THREAD_OFF(r->t_adver_timer);
+ EVENT_OFF(r->t_adver_timer);
if (r->vr->version == 3) {
r->master_adver_interval =
htons(pkt->hdr.v3.adver_int);
}
vrrp_recalculate_timers(r);
- THREAD_OFF(r->t_master_down_timer);
- thread_add_timer_msec(master,
- vrrp_master_down_timer_expire, r,
- r->master_down_interval * CS2MS,
- &r->t_master_down_timer);
+ EVENT_OFF(r->t_master_down_timer);
+ event_add_timer_msec(master,
+ vrrp_master_down_timer_expire, r,
+ r->master_down_interval * CS2MS,
+ &r->t_master_down_timer);
vrrp_change_state(r, VRRP_STATE_BACKUP);
} else {
/* Discard advertisement */
break;
case VRRP_STATE_BACKUP:
if (pkt->hdr.priority == 0) {
- THREAD_OFF(r->t_master_down_timer);
- thread_add_timer_msec(
+ EVENT_OFF(r->t_master_down_timer);
+ event_add_timer_msec(
master, vrrp_master_down_timer_expire, r,
r->skew_time * CS2MS, &r->t_master_down_timer);
} else if (!r->vr->preempt_mode
ntohs(pkt->hdr.v3.adver_int);
}
vrrp_recalculate_timers(r);
- THREAD_OFF(r->t_master_down_timer);
- thread_add_timer_msec(master,
- vrrp_master_down_timer_expire, r,
- r->master_down_interval * CS2MS,
- &r->t_master_down_timer);
+ EVENT_OFF(r->t_master_down_timer);
+ event_add_timer_msec(master,
+ vrrp_master_down_timer_expire, r,
+ r->master_down_interval * CS2MS,
+ &r->t_master_down_timer);
} else if (r->vr->preempt_mode
&& pkt->hdr.priority < r->priority) {
/* Discard advertisement */
/*
* Read and process next IPvX datagram.
*/
-static void vrrp_read(struct thread *thread)
+static void vrrp_read(struct event *thread)
{
- struct vrrp_router *r = THREAD_ARG(thread);
+ struct vrrp_router *r = EVENT_ARG(thread);
struct vrrp_pkt *pkt;
ssize_t pktsize;
memset(r->ibuf, 0x00, sizeof(r->ibuf));
if (resched)
- thread_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
+ event_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
}
/*
vrrp_zebra_radv_set(r, false);
/* Disable Adver_Timer */
- THREAD_OFF(r->t_adver_timer);
+ EVENT_OFF(r->t_adver_timer);
r->advert_pending = false;
r->garp_pending = false;
/*
* Called when Adver_Timer expires.
*/
-static void vrrp_adver_timer_expire(struct thread *thread)
+static void vrrp_adver_timer_expire(struct event *thread)
{
- struct vrrp_router *r = THREAD_ARG(thread);
+ struct vrrp_router *r = EVENT_ARG(thread);
DEBUGD(&vrrp_dbg_proto,
VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
vrrp_send_advertisement(r);
/* Reset the Adver_Timer to Advertisement_Interval */
- thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
- r->vr->advertisement_interval * CS2MS,
- &r->t_adver_timer);
+ event_add_timer_msec(master, vrrp_adver_timer_expire, r,
+ r->vr->advertisement_interval * CS2MS,
+ &r->t_adver_timer);
} else {
zlog_err(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
"Adver_Timer expired in state '%s'; this is a bug",
/*
* Called when Master_Down_Timer expires.
*/
-static void vrrp_master_down_timer_expire(struct thread *thread)
+static void vrrp_master_down_timer_expire(struct event *thread)
{
- struct vrrp_router *r = THREAD_ARG(thread);
+ struct vrrp_router *r = EVENT_ARG(thread);
zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
"Master_Down_Timer expired",
r->vr->vrid, family2str(r->family));
- thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
- r->vr->advertisement_interval * CS2MS,
- &r->t_adver_timer);
+ event_add_timer_msec(master, vrrp_adver_timer_expire, r,
+ r->vr->advertisement_interval * CS2MS,
+ &r->t_adver_timer);
vrrp_change_state(r, VRRP_STATE_MASTER);
}
}
/* Schedule listener */
- thread_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
+ event_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
/* Configure effective priority */
assert(listhead(r->addrs));
}
if (r->priority == VRRP_PRIO_MASTER) {
- thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
- r->vr->advertisement_interval * CS2MS,
- &r->t_adver_timer);
+ event_add_timer_msec(master, vrrp_adver_timer_expire, r,
+ r->vr->advertisement_interval * CS2MS,
+ &r->t_adver_timer);
vrrp_change_state(r, VRRP_STATE_MASTER);
} else {
r->master_adver_interval = r->vr->advertisement_interval;
vrrp_recalculate_timers(r);
- thread_add_timer_msec(master, vrrp_master_down_timer_expire, r,
- r->master_down_interval * CS2MS,
- &r->t_master_down_timer);
+ event_add_timer_msec(master, vrrp_master_down_timer_expire, r,
+ r->master_down_interval * CS2MS,
+ &r->t_master_down_timer);
vrrp_change_state(r, VRRP_STATE_BACKUP);
}
}
/* Cancel all timers */
- THREAD_OFF(r->t_adver_timer);
- THREAD_OFF(r->t_master_down_timer);
- THREAD_OFF(r->t_read);
- THREAD_OFF(r->t_write);
+ EVENT_OFF(r->t_adver_timer);
+ EVENT_OFF(r->t_master_down_timer);
+ EVENT_OFF(r->t_read);
+ EVENT_OFF(r->t_write);
/* Protodown macvlan */
if (r->mvl_ifp)
list_delete(&vrs);
- hash_clean(vrrp_vrouters_hash, NULL);
- hash_free(vrrp_vrouters_hash);
+ hash_clean_and_free(&vrrp_vrouters_hash, NULL);
}
#include "lib/northbound.h"
#include "lib/privs.h"
#include "lib/stream.h"
-#include "lib/thread.h"
+#include "lib/frrevent.h"
#include "lib/vty.h"
/* Global definitions */
extern struct vrrp_defaults vd;
/* threadmaster */
-extern struct thread_master *master;
+extern struct event_loop *master;
/* privileges */
extern struct zebra_privs_t vrrp_privs;
uint32_t trans_cnt;
} stats;
- struct thread *t_master_down_timer;
- struct thread *t_adver_timer;
- struct thread *t_read;
- struct thread *t_write;
+ struct event *t_master_down_timer;
+ struct event *t_adver_timer;
+ struct event *t_read;
+ struct event *t_write;
};
/*
*/
#include <zebra.h>
+#include <getopt.h>
+
#include <lib/version.h>
#include "lib/command.h"
#include "lib/filter.h"
-#include "lib/getopt.h"
#include "lib/if.h"
#include "lib/libfrr.h"
#include "lib/log.h"
#include "lib/nexthop.h"
#include "lib/privs.h"
#include "lib/sigevent.h"
-#include "lib/thread.h"
+#include "lib/frrevent.h"
#include "lib/vrf.h"
#include "lib/vty.h"
struct option longopts[] = { {0} };
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
static struct frr_daemon_info vrrpd_di;
/* VTY should add timestamp */
bool vtysh_add_timestamp;
-/* VTY shell client structure */
-struct vtysh_client {
- int fd;
- const char *name;
- int flag;
- char path[MAXPATHLEN];
- struct vtysh_client *next;
-
- struct thread *log_reader;
- int log_fd;
- uint32_t lost_msgs;
-};
-
static bool stderr_tty;
static bool stderr_stdout_same;
/* --- */
+/*
+ * When updating this array, remember to change the array size here and in
+ * vtysh.h
+ */
struct vtysh_client vtysh_client[] = {
{.name = "mgmtd", .flag = VTYSH_MGMTD},
{.name = "zebra", .flag = VTYSH_ZEBRA},
int ret;
const char *fname = argv[1]->arg;
- ret = vtysh_read_config(fname, true);
+ ret = vtysh_apply_config(fname, true, false);
/* Return to enable mode - the 'read_config' api leaves us up a level */
vtysh_execute_no_pager("enable");
text + textpos);
}
-static void vtysh_log_read(struct thread *thread)
+static void vtysh_log_read(struct event *thread)
{
- struct vtysh_client *vclient = THREAD_ARG(thread);
+ struct vtysh_client *vclient = EVENT_ARG(thread);
struct {
struct zlog_live_hdr hdr;
char text[4096];
const char *text;
ssize_t ret;
- thread_add_read(master, vtysh_log_read, vclient, vclient->log_fd,
- &vclient->log_reader);
+ event_add_read(master, vtysh_log_read, vclient, vclient->log_fd,
+ &vclient->log_reader);
ret = recv(vclient->log_fd, &buf, sizeof(buf), 0);
"log monitor connection closed unexpectedly");
buf.hdr.textlen = strlen(buf.text);
- THREAD_OFF(vclient->log_reader);
+ EVENT_OFF(vclient->log_reader);
close(vclient->log_fd);
vclient->log_fd = -1;
if (fd != -1) {
set_nonblocking(fd);
vclient->log_fd = fd;
- thread_add_read(master, vtysh_log_read, vclient,
- vclient->log_fd,
- &vclient->log_reader);
+ event_add_read(master, vtysh_log_read, vclient,
+ vclient->log_fd,
+ &vclient->log_reader);
}
if (ret != CMD_SUCCESS) {
vty_out(vty, "%% failed to enable logs on %s\n",
* a close notification...
*/
if (vclient->log_fd != -1) {
- THREAD_OFF(vclient->log_reader);
+ EVENT_OFF(vclient->log_reader);
close(vclient->log_fd);
vclient->log_fd = -1;
#include "memory.h"
DECLARE_MGROUP(MVTYSH);
-struct thread_master;
+struct event_loop;
-extern struct thread_master *master;
+extern struct event_loop *master;
#define VTYSH_ZEBRA 0x00001
#define VTYSH_RIPD 0x00002
int vtysh_mark_file(const char *filename);
-int vtysh_read_config(const char *filename, bool dry_run);
+int vtysh_apply_config(const char *config_file_path, bool dry_run, bool fork);
int vtysh_write_config_integrated(void);
void vtysh_config_parse_line(void *, const char *);
extern bool vtysh_add_timestamp;
+struct vtysh_client {
+ int fd;
+ const char *name;
+ int flag;
+ char path[MAXPATHLEN];
+ struct vtysh_client *next;
+
+ struct event *log_reader;
+ int log_fd;
+ uint32_t lost_msgs;
+};
+
+extern struct vtysh_client vtysh_client[22];
+
#endif /* VTYSH_H */
*/
#include <zebra.h>
+#include <sys/wait.h>
#include "command.h"
#include "linklist.h"
return (ret);
}
-/* Read up configuration file from config_default_dir. */
-int vtysh_read_config(const char *config_default_dir, bool dry_run)
+/*
+ * Read configuration file and send it to all connected daemons
+ */
+static int vtysh_read_config(const char *config_file_path, bool dry_run)
{
FILE *confp = NULL;
bool save;
int ret;
- confp = fopen(config_default_dir, "r");
+ confp = fopen(config_file_path, "r");
if (confp == NULL) {
fprintf(stderr,
"%% Can't open configuration file %s due to '%s'.\n",
- config_default_dir, safe_strerror(errno));
+ config_file_path, safe_strerror(errno));
return CMD_ERR_NO_FILE;
}
vtysh_add_timestamp = save;
- return (ret);
+ return ret;
+}
+
+int vtysh_apply_config(const char *config_file_path, bool dry_run, bool do_fork)
+{
+ /*
+ * We need to apply the whole config file to all daemons. Instead of
+ * having one client talk to N daemons, we fork N times and let each
+ * child handle one daemon.
+ */
+ pid_t fork_pid = getpid();
+ int status = 0;
+ int ret;
+ int my_client_type;
+ char my_client[64];
+
+ if (do_fork) {
+ for (unsigned int i = 0; i < array_size(vtysh_client); i++) {
+ /* Store name of client this fork will handle */
+ strlcpy(my_client, vtysh_client[i].name,
+ sizeof(my_client));
+ my_client_type = vtysh_client[i].flag;
+ fork_pid = fork();
+
+ /* If child, break */
+ if (fork_pid == 0)
+ break;
+ }
+
+ /* parent, wait for children */
+ if (fork_pid != 0) {
+ int keep_status = 0;
+
+ fprintf(stdout,
+ "Waiting for children to finish applying config...\n");
+ while (wait(&status) > 0) {
+ if (!keep_status && WEXITSTATUS(status))
+ keep_status = WEXITSTATUS(status);
+ }
+
+ /*
+ * This will return the first status received
+ * that failed( if that happens ). This is
+ * good enough for the moment
+ */
+ return keep_status;
+ }
+
+ /*
+ * children, grow up to be cowboys
+ */
+ for (unsigned int i = 0; i < array_size(vtysh_client); i++) {
+ if (my_client_type != vtysh_client[i].flag) {
+ struct vtysh_client *cl;
+
+ /*
+ * If this is a client we aren't responsible
+ * for, disconnect
+ */
+ for (cl = &vtysh_client[i]; cl; cl = cl->next) {
+ if (cl->fd >= 0)
+ close(cl->fd);
+ cl->fd = -1;
+ }
+ } else if (vtysh_client[i].fd == -1 &&
+ vtysh_client[i].next == NULL) {
+ /*
+ * If this is the client we are responsible
+ * for, but we aren't already connected to that
+ * client, that means the client isn't up in
+ * the first place and we can exit early
+ */
+ exit(0);
+ }
+ }
+
+ fprintf(stdout, "[%d|%s] sending configuration\n", getpid(),
+ my_client);
+ }
+
+ ret = vtysh_read_config(config_file_path, dry_run);
+
+ if (ret) {
+ if (do_fork)
+ fprintf(stderr,
+ "[%d|%s] Configuration file[%s] processing failure: %d\n",
+ getpid(), my_client, frr_config, ret);
+ else
+ fprintf(stderr,
+ "Configuration file[%s] processing failure: %d\n",
+ frr_config, ret);
+ } else if (do_fork) {
+ fprintf(stderr, "[%d|%s] done\n", getpid(), my_client);
+ exit(0);
+ }
+
+ return ret;
}
/* We don't write vtysh specific into file from vtysh. vtysh.conf should
#include <sys/un.h>
#include <setjmp.h>
-#include <sys/wait.h>
#include <pwd.h>
#include <sys/file.h>
#include <unistd.h>
int user_mode;
/* Master of threads. */
-struct thread_master *master;
+struct event_loop *master;
/* Command logging */
FILE *logfile;
"-u --user Run as an unprivileged user\n"
"-w, --writeconfig Write integrated config (frr.conf) and exit\n"
"-H, --histfile Override history file\n"
+ "-t, --timestamp Print a timestamp before going to shell or reading the configuration\n"
+ " --no-fork Don't fork clients to handle daemons (slower for large configs)\n"
"-h, --help Display this help and exit\n\n"
"Note that multiple commands may be executed from the command\n"
"line by passing multiple -c args, or by embedding linefeed\n"
/* VTY shell options, we use GNU getopt library. */
#define OPTION_VTYSOCK 1000
#define OPTION_CONFDIR 1001
+#define OPTION_NOFORK 1002
struct option longopts[] = {
{"boot", no_argument, NULL, 'b'},
/* For compatibility with older zebra/quagga versions */
{"pathspace", required_argument, NULL, 'N'},
{"user", no_argument, NULL, 'u'},
{"timestamp", no_argument, NULL, 't'},
+ {"no-fork", no_argument, NULL, OPTION_NOFORK},
{0}};
bool vtysh_loop_exited;
-static struct thread *vtysh_rl_read_thread;
+static struct event *vtysh_rl_read_thread;
-static void vtysh_rl_read(struct thread *thread)
+static void vtysh_rl_read(struct event *thread)
{
- thread_add_read(master, vtysh_rl_read, NULL, STDIN_FILENO,
- &vtysh_rl_read_thread);
+ event_add_read(master, vtysh_rl_read, NULL, STDIN_FILENO,
+ &vtysh_rl_read_thread);
rl_callback_read_char();
}
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
static void vtysh_rl_run(void)
{
- struct thread thread;
+ struct event thread;
- master = thread_master_create(NULL);
+ master = event_master_create(NULL);
rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback);
- thread_add_read(master, vtysh_rl_read, NULL, STDIN_FILENO,
- &vtysh_rl_read_thread);
+ event_add_read(master, vtysh_rl_read, NULL, STDIN_FILENO,
+ &vtysh_rl_read_thread);
- while (!vtysh_loop_exited && thread_fetch(master, &thread))
- thread_call(&thread);
+ while (!vtysh_loop_exited && event_fetch(master, &thread))
+ event_call(&thread);
if (!vtysh_loop_exited)
rl_callback_handler_remove();
- thread_master_free(master);
+ event_master_free(master);
}
static void log_it(const char *line)
int dryrun = 0;
int boot_flag = 0;
bool ts_flag = false;
+ bool no_fork = false;
const char *daemon_name = NULL;
const char *inputfile = NULL;
struct cmd_rec {
ditch_suid = 1; /* option disables SUID */
snprintf(sysconfdir, sizeof(sysconfdir), "%s/", optarg);
break;
+ case OPTION_NOFORK:
+ no_fork = true;
+ break;
case 'N':
if (strchr(optarg, '/') || strchr(optarg, '.')) {
fprintf(stderr,
}
}
+ /* No need for forks if we're talking to 1 daemon */
+ if (daemon_name)
+ no_fork = true;
+
if (ditch_suid) {
elevuid = realuid;
elevgid = realgid;
/* Read vtysh configuration file before connecting to daemons.
* (file may not be readable to calling user in SUID mode) */
suid_on();
- vtysh_read_config(vtysh_config, dryrun);
+ vtysh_apply_config(vtysh_config, dryrun, false);
suid_off();
}
/* Error code library system */
/* Start execution only if not in dry-run mode */
if (dryrun && !cmd) {
if (inputfile) {
- ret = vtysh_read_config(inputfile, dryrun);
+ ret = vtysh_apply_config(inputfile, dryrun, false);
} else {
- ret = vtysh_read_config(frr_config, dryrun);
+ ret = vtysh_apply_config(frr_config, dryrun, false);
}
exit(ret);
return vtysh_write_config_integrated();
}
- if (inputfile) {
+ if (boot_flag)
+ inputfile = frr_config;
+
+ if (inputfile || boot_flag) {
vtysh_flock_config(inputfile);
- ret = vtysh_read_config(inputfile, dryrun);
+ ret = vtysh_apply_config(inputfile, dryrun, !no_fork);
vtysh_unflock_config();
+
+ if (no_error)
+ ret = 0;
+
exit(ret);
}
exit(0);
}
- /* Boot startup configuration file. */
- if (boot_flag) {
- vtysh_flock_config(frr_config);
- ret = vtysh_read_config(frr_config, dryrun);
- vtysh_unflock_config();
- if (ret) {
- fprintf(stderr,
- "Configuration file[%s] processing failure: %d\n",
- frr_config, ret);
- if (no_error)
- exit(0);
- else
- exit(ret);
- } else
- exit(0);
- }
-
vtysh_readline_init();
vty_hello(vty);
*/
#include <zebra.h>
-#include <thread.h>
+#include "frrevent.h"
#include <log.h>
#include <network.h>
#include <sigevent.h>
DEFINE_MTYPE_STATIC(WATCHFRR, WATCHFRR_DAEMON, "watchfrr daemon entry");
/* Needs to be global, referenced somewhere inside libfrr. */
-struct thread_master *master;
+struct event_loop *master;
static bool watch_only = false;
const char *pathspace;
pid_t pid;
struct timeval time;
long interval;
- struct thread *t_kill;
+ struct event *t_kill;
int kills;
};
static struct global_state {
enum restart_phase phase;
- struct thread *t_phase_hanging;
- struct thread *t_startup_timeout;
- struct thread *t_operational;
+ struct event *t_phase_hanging;
+ struct event *t_startup_timeout;
+ struct event *t_operational;
const char *vtydir;
long period;
long timeout;
int fd;
struct timeval echo_sent;
unsigned int connect_tries;
- struct thread *t_wakeup;
- struct thread *t_read;
- struct thread *t_write;
+ struct event *t_wakeup;
+ struct event *t_read;
+ struct event *t_write;
struct daemon *next;
struct restart_info restart;
{NULL, 0, NULL, 0}};
static int try_connect(struct daemon *dmn);
-static void wakeup_send_echo(struct thread *t_wakeup);
+static void wakeup_send_echo(struct event *t_wakeup);
static void try_restart(struct daemon *dmn);
static void phase_check(void);
static void restart_done(struct daemon *dmn);
return result;
}
-static void restart_kill(struct thread *t_kill)
+static void restart_kill(struct event *t_kill)
{
- struct restart_info *restart = THREAD_ARG(t_kill);
+ struct restart_info *restart = EVENT_ARG(t_kill);
struct timeval delay;
time_elapsed(&delay, &restart->time);
zlog_err(
"%s %s child process appears to still be reading configuration, delaying for another %lu time",
restart->what, restart->name, gs.restart_timeout);
- thread_add_timer(master, restart_kill, restart,
- gs.restart_timeout, &restart->t_kill);
+ event_add_timer(master, restart_kill, restart,
+ gs.restart_timeout, &restart->t_kill);
return;
}
(long)delay.tv_sec, (restart->kills ? SIGKILL : SIGTERM));
kill(-restart->pid, (restart->kills ? SIGKILL : SIGTERM));
restart->kills++;
- thread_add_timer(master, restart_kill, restart, gs.restart_timeout,
- &restart->t_kill);
+ event_add_timer(master, restart_kill, restart, gs.restart_timeout,
+ &restart->t_kill);
}
static struct restart_info *find_child(pid_t child)
what = restart->what;
restart->pid = 0;
gs.numpids--;
- thread_cancel(&restart->t_kill);
+ event_cancel(&restart->t_kill);
/* Update restart time to reflect the time the command
* completed. */
snprintf(cmd, sizeof(cmd), command, restart->name);
#pragma GCC diagnostic pop
if ((restart->pid = run_background(cmd)) > 0) {
- thread_add_timer(master, restart_kill, restart,
- gs.restart_timeout, &restart->t_kill);
+ event_add_timer(master, restart_kill, restart,
+ gs.restart_timeout, &restart->t_kill);
restart->what = cmdtype;
gs.numpids++;
} else
#define SET_READ_HANDLER(DMN) \
do { \
(DMN)->t_read = NULL; \
- thread_add_read(master, handle_read, (DMN), (DMN)->fd, \
- &(DMN)->t_read); \
+ event_add_read(master, handle_read, (DMN), (DMN)->fd, \
+ &(DMN)->t_read); \
} while (0);
#define SET_WAKEUP_DOWN(DMN) \
do { \
(DMN)->t_wakeup = NULL; \
- thread_add_timer_msec(master, wakeup_down, (DMN), \
- FUZZY(gs.period), &(DMN)->t_wakeup); \
+ event_add_timer_msec(master, wakeup_down, (DMN), \
+ FUZZY(gs.period), &(DMN)->t_wakeup); \
} while (0);
#define SET_WAKEUP_UNRESPONSIVE(DMN) \
do { \
(DMN)->t_wakeup = NULL; \
- thread_add_timer_msec(master, wakeup_unresponsive, (DMN), \
- FUZZY(gs.period), &(DMN)->t_wakeup); \
+ event_add_timer_msec(master, wakeup_unresponsive, (DMN), \
+ FUZZY(gs.period), &(DMN)->t_wakeup); \
} while (0);
#define SET_WAKEUP_ECHO(DMN) \
do { \
(DMN)->t_wakeup = NULL; \
- thread_add_timer_msec(master, wakeup_send_echo, (DMN), \
- FUZZY(gs.period), &(DMN)->t_wakeup); \
+ event_add_timer_msec(master, wakeup_send_echo, (DMN), \
+ FUZZY(gs.period), &(DMN)->t_wakeup); \
} while (0);
-static void wakeup_down(struct thread *t_wakeup)
+static void wakeup_down(struct event *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
+ struct daemon *dmn = EVENT_ARG(t_wakeup);
dmn->t_wakeup = NULL;
if (try_connect(dmn) < 0)
try_restart(dmn);
}
-static void wakeup_init(struct thread *t_wakeup)
+static void wakeup_init(struct event *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
+ struct daemon *dmn = EVENT_ARG(t_wakeup);
dmn->t_wakeup = NULL;
if (try_connect(dmn) < 0) {
dmn->name, state_str[dmn->state]);
return;
}
- THREAD_OFF(dmn->t_wakeup);
+ EVENT_OFF(dmn->t_wakeup);
if (try_connect(dmn) < 0)
SET_WAKEUP_DOWN(dmn);
}
-static void daemon_restarting_operational(struct thread *thread)
+static void daemon_restarting_operational(struct event *thread)
{
systemd_send_status("FRR Operational");
}
close(dmn->fd);
dmn->fd = -1;
}
- THREAD_OFF(dmn->t_read);
- THREAD_OFF(dmn->t_write);
- THREAD_OFF(dmn->t_wakeup);
+ EVENT_OFF(dmn->t_read);
+ EVENT_OFF(dmn->t_write);
+ EVENT_OFF(dmn->t_wakeup);
if (try_connect(dmn) < 0)
SET_WAKEUP_DOWN(dmn);
phase_check();
}
-static void handle_read(struct thread *t_read)
+static void handle_read(struct event *t_read)
{
- struct daemon *dmn = THREAD_ARG(t_read);
+ struct daemon *dmn = EVENT_ARG(t_read);
static const char resp[sizeof(PING_TOKEN) + 4] = PING_TOKEN "\n";
char buf[sizeof(resp) + 100];
ssize_t rc;
dmn->name, (long)delay.tv_sec, (long)delay.tv_usec);
SET_READ_HANDLER(dmn);
- thread_cancel(&dmn->t_wakeup);
+ event_cancel(&dmn->t_wakeup);
SET_WAKEUP_ECHO(dmn);
}
if (gs.numdown == 0) {
daemon_send_ready(0);
- THREAD_OFF(gs.t_operational);
+ EVENT_OFF(gs.t_operational);
- thread_add_timer(master, daemon_restarting_operational, NULL,
- gs.operational_timeout, &gs.t_operational);
+ event_add_timer(master, daemon_restarting_operational, NULL,
+ gs.operational_timeout, &gs.t_operational);
}
SET_WAKEUP_ECHO(dmn);
phase_check();
}
-static void check_connect(struct thread *t_write)
+static void check_connect(struct event *t_write)
{
- struct daemon *dmn = THREAD_ARG(t_write);
+ struct daemon *dmn = EVENT_ARG(t_write);
int sockerr;
socklen_t reslen = sizeof(sockerr);
daemon_up(dmn, "delayed connect succeeded");
}
-static void wakeup_connect_hanging(struct thread *t_wakeup)
+static void wakeup_connect_hanging(struct event *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
+ struct daemon *dmn = EVENT_ARG(t_wakeup);
char why[100];
dmn->t_wakeup = NULL;
zlog_debug("%s: connection in progress", dmn->name);
dmn->state = DAEMON_CONNECTING;
dmn->fd = sock;
- thread_add_write(master, check_connect, dmn, dmn->fd,
- &dmn->t_write);
- thread_add_timer(master, wakeup_connect_hanging, dmn,
- gs.timeout, &dmn->t_wakeup);
+ event_add_write(master, check_connect, dmn, dmn->fd,
+ &dmn->t_write);
+ event_add_timer(master, wakeup_connect_hanging, dmn, gs.timeout,
+ &dmn->t_wakeup);
SET_READ_HANDLER(dmn);
return 0;
}
return 1;
}
-static void phase_hanging(struct thread *t_hanging)
+static void phase_hanging(struct event *t_hanging)
{
gs.t_phase_hanging = NULL;
flog_err(EC_WATCHFRR_CONNECTION,
static void set_phase(enum restart_phase new_phase)
{
gs.phase = new_phase;
- thread_cancel(&gs.t_phase_hanging);
+ event_cancel(&gs.t_phase_hanging);
- thread_add_timer(master, phase_hanging, NULL, PHASE_TIMEOUT,
- &gs.t_phase_hanging);
+ event_add_timer(master, phase_hanging, NULL, PHASE_TIMEOUT,
+ &gs.t_phase_hanging);
}
static void phase_check(void)
gs.start_command, 1, 0);
}
gs.phase = PHASE_NONE;
- THREAD_OFF(gs.t_phase_hanging);
+ EVENT_OFF(gs.t_phase_hanging);
zlog_notice("Phased global restart has completed.");
break;
}
run_job(&gs.restart, "restart", gs.restart_command, 0, 1);
}
-static void wakeup_unresponsive(struct thread *t_wakeup)
+static void wakeup_unresponsive(struct event *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
+ struct daemon *dmn = EVENT_ARG(t_wakeup);
dmn->t_wakeup = NULL;
if (dmn->state != DAEMON_UNRESPONSIVE)
}
}
-static void wakeup_no_answer(struct thread *t_wakeup)
+static void wakeup_no_answer(struct event *t_wakeup)
{
- struct daemon *dmn = THREAD_ARG(t_wakeup);
+ struct daemon *dmn = EVENT_ARG(t_wakeup);
dmn->t_wakeup = NULL;
dmn->state = DAEMON_UNRESPONSIVE;
try_restart(dmn);
}
-static void wakeup_send_echo(struct thread *t_wakeup)
+static void wakeup_send_echo(struct event *t_wakeup)
{
static const char echocmd[] = "echo " PING_TOKEN;
ssize_t rc;
- struct daemon *dmn = THREAD_ARG(t_wakeup);
+ struct daemon *dmn = EVENT_ARG(t_wakeup);
dmn->t_wakeup = NULL;
if (((rc = write(dmn->fd, echocmd, sizeof(echocmd))) < 0)
daemon_down(dmn, why);
} else {
gettimeofday(&dmn->echo_sent, NULL);
- thread_add_timer(master, wakeup_no_answer, dmn, gs.timeout,
- &dmn->t_wakeup);
+ event_add_timer(master, wakeup_no_answer, dmn, gs.timeout,
+ &dmn->t_wakeup);
}
}
return res;
}
-static void startup_timeout(struct thread *t_wakeup)
+static void startup_timeout(struct event *t_wakeup)
{
daemon_send_ready(1);
}
struct daemon *dmn, **add = &gs.daemons;
char alldaemons[512] = "", *p = alldaemons;
- thread_add_timer_msec(master, startup_timeout, NULL, STARTUP_TIMEOUT,
- &gs.t_startup_timeout);
+ event_add_timer_msec(master, startup_timeout, NULL, STARTUP_TIMEOUT,
+ &gs.t_startup_timeout);
for (i = optind; i < argc; i++) {
dmn = XCALLOC(MTYPE_WATCHFRR_DAEMON, sizeof(*dmn));
gs.numdaemons++;
gs.numdown++;
dmn->fd = -1;
- thread_add_timer_msec(master, wakeup_init, dmn, 0,
- &dmn->t_wakeup);
+ event_add_timer_msec(master, wakeup_init, dmn, 0,
+ &dmn->t_wakeup);
dmn->restart.interval = gs.min_restart_interval;
*add = dmn;
add = &dmn->next;
zd_dpdk_vty_init();
frr_with_privs (&zserv_privs) {
- rc = rte_eal_init(ARRAY_SIZE(argv), argv);
+ rc = rte_eal_init(array_size(argv), argv);
}
if (rc < 0) {
zlog_warn("EAL init failed %s", rte_strerror(rte_errno));
}
-static int zd_dpdk_plugin_init(struct thread_master *tm)
+static int zd_dpdk_plugin_init(struct event_loop *tm)
{
int ret;
/* data plane events. */
struct zebra_dplane_provider *prov;
struct frr_pthread *fthread;
- struct thread *t_connect;
- struct thread *t_read;
- struct thread *t_write;
- struct thread *t_event;
- struct thread *t_nhg;
- struct thread *t_dequeue;
+ struct event *t_connect;
+ struct event *t_read;
+ struct event *t_write;
+ struct event *t_event;
+ struct event *t_nhg;
+ struct event *t_dequeue;
/* zebra events. */
- struct thread *t_lspreset;
- struct thread *t_lspwalk;
- struct thread *t_nhgreset;
- struct thread *t_nhgwalk;
- struct thread *t_ribreset;
- struct thread *t_ribwalk;
- struct thread *t_rmacreset;
- struct thread *t_rmacwalk;
+ struct event *t_lspreset;
+ struct event *t_lspwalk;
+ struct event *t_nhgreset;
+ struct event *t_nhgwalk;
+ struct event *t_ribreset;
+ struct event *t_ribwalk;
+ struct event *t_rmacreset;
+ struct event *t_rmacwalk;
/* Statistic counters. */
struct {
};
#define FPM_RECONNECT(fnc) \
- thread_add_event((fnc)->fthread->master, fpm_process_event, (fnc), \
- FNE_INTERNAL_RECONNECT, &(fnc)->t_event)
+ event_add_event((fnc)->fthread->master, fpm_process_event, (fnc), \
+ FNE_INTERNAL_RECONNECT, &(fnc)->t_event)
#define WALK_FINISH(fnc, ev) \
- thread_add_event((fnc)->fthread->master, fpm_process_event, (fnc), \
- (ev), NULL)
+ event_add_event((fnc)->fthread->master, fpm_process_event, (fnc), \
+ (ev), NULL)
/*
* Prototypes.
*/
-static void fpm_process_event(struct thread *t);
+static void fpm_process_event(struct event *t);
static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx);
-static void fpm_lsp_send(struct thread *t);
-static void fpm_lsp_reset(struct thread *t);
-static void fpm_nhg_send(struct thread *t);
-static void fpm_nhg_reset(struct thread *t);
-static void fpm_rib_send(struct thread *t);
-static void fpm_rib_reset(struct thread *t);
-static void fpm_rmac_send(struct thread *t);
-static void fpm_rmac_reset(struct thread *t);
+static void fpm_lsp_send(struct event *t);
+static void fpm_lsp_reset(struct event *t);
+static void fpm_nhg_send(struct event *t);
+static void fpm_nhg_reset(struct event *t);
+static void fpm_rib_send(struct event *t);
+static void fpm_rib_reset(struct event *t);
+static void fpm_rmac_send(struct event *t);
+static void fpm_rmac_reset(struct event *t);
/*
* CLI.
memcpy(&sin6->sin6_addr, naddr, sizeof(sin6->sin6_addr));
ask_reconnect:
- thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
- FNE_RECONNECT, &gfnc->t_event);
+ event_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
+ FNE_RECONNECT, &gfnc->t_event);
return CMD_SUCCESS;
}
"FPM remote listening server port\n"
"Remote FPM server port\n")
{
- thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
- FNE_DISABLE, &gfnc->t_event);
+ event_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
+ FNE_DISABLE, &gfnc->t_event);
return CMD_SUCCESS;
}
if (gfnc->use_nhg)
return CMD_SUCCESS;
- thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
- FNE_TOGGLE_NHG, &gfnc->t_nhg);
+ event_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
+ FNE_TOGGLE_NHG, &gfnc->t_nhg);
return CMD_SUCCESS;
}
if (!gfnc->use_nhg)
return CMD_SUCCESS;
- thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
- FNE_TOGGLE_NHG, &gfnc->t_nhg);
+ event_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
+ FNE_TOGGLE_NHG, &gfnc->t_nhg);
return CMD_SUCCESS;
}
FPM_STR
"FPM statistic counters\n")
{
- thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
- FNE_RESET_COUNTERS, &gfnc->t_event);
+ event_add_event(gfnc->fthread->master, fpm_process_event, gfnc,
+ FNE_RESET_COUNTERS, &gfnc->t_event);
return CMD_SUCCESS;
}
/*
* FPM functions.
*/
-static void fpm_connect(struct thread *t);
+static void fpm_connect(struct event *t);
static void fpm_reconnect(struct fpm_nl_ctx *fnc)
{
/* Cancel all zebra threads first. */
- thread_cancel_async(zrouter.master, &fnc->t_lspreset, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_lspwalk, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_nhgreset, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_nhgwalk, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_ribreset, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_ribwalk, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_rmacreset, NULL);
- thread_cancel_async(zrouter.master, &fnc->t_rmacwalk, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_lspreset, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_lspwalk, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_nhgreset, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_nhgwalk, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_ribreset, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_ribwalk, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_rmacreset, NULL);
+ event_cancel_async(zrouter.master, &fnc->t_rmacwalk, NULL);
/*
* Grab the lock to empty the streams (data plane might try to
stream_reset(fnc->ibuf);
stream_reset(fnc->obuf);
- THREAD_OFF(fnc->t_read);
- THREAD_OFF(fnc->t_write);
+ EVENT_OFF(fnc->t_read);
+ EVENT_OFF(fnc->t_write);
/* FPM is disabled, don't attempt to connect. */
if (fnc->disabled)
return;
- thread_add_timer(fnc->fthread->master, fpm_connect, fnc, 3,
- &fnc->t_connect);
+ event_add_timer(fnc->fthread->master, fpm_connect, fnc, 3,
+ &fnc->t_connect);
}
-static void fpm_read(struct thread *t)
+static void fpm_read(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
fpm_msg_hdr_t fpm;
ssize_t rv;
char buf[65535];
}
/* Schedule the next read */
- thread_add_read(fnc->fthread->master, fpm_read, fnc, fnc->socket,
- &fnc->t_read);
+ event_add_read(fnc->fthread->master, fpm_read, fnc, fnc->socket,
+ &fnc->t_read);
/* We've got an interruption. */
if (rv == -2)
stream_reset(fnc->ibuf);
}
-static void fpm_write(struct thread *t)
+static void fpm_write(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
socklen_t statuslen;
ssize_t bwritten;
int rv, status;
* Starting with LSPs walk all FPM objects, marking them
* as unsent and then replaying them.
*/
- thread_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0,
- &fnc->t_lspreset);
+ event_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0,
+ &fnc->t_lspreset);
/* Permit receiving messages now. */
- thread_add_read(fnc->fthread->master, fpm_read, fnc,
- fnc->socket, &fnc->t_read);
+ event_add_read(fnc->fthread->master, fpm_read, fnc, fnc->socket,
+ &fnc->t_read);
}
frr_mutex_lock_autounlock(&fnc->obuf_mutex);
/* Stream is not empty yet, we must schedule more writes. */
if (STREAM_READABLE(fnc->obuf)) {
stream_pulldown(fnc->obuf);
- thread_add_write(fnc->fthread->master, fpm_write, fnc,
- fnc->socket, &fnc->t_write);
+ event_add_write(fnc->fthread->master, fpm_write, fnc,
+ fnc->socket, &fnc->t_write);
return;
}
}
-static void fpm_connect(struct thread *t)
+static void fpm_connect(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
struct sockaddr_in *sin = (struct sockaddr_in *)&fnc->addr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&fnc->addr;
socklen_t slen;
if (sock == -1) {
zlog_err("%s: fpm socket failed: %s", __func__,
strerror(errno));
- thread_add_timer(fnc->fthread->master, fpm_connect, fnc, 3,
- &fnc->t_connect);
+ event_add_timer(fnc->fthread->master, fpm_connect, fnc, 3,
+ &fnc->t_connect);
return;
}
close(sock);
zlog_warn("%s: fpm connection failed: %s", __func__,
strerror(errno));
- thread_add_timer(fnc->fthread->master, fpm_connect, fnc, 3,
- &fnc->t_connect);
+ event_add_timer(fnc->fthread->master, fpm_connect, fnc, 3,
+ &fnc->t_connect);
return;
}
fnc->connecting = (errno == EINPROGRESS);
fnc->socket = sock;
if (!fnc->connecting)
- thread_add_read(fnc->fthread->master, fpm_read, fnc, sock,
- &fnc->t_read);
- thread_add_write(fnc->fthread->master, fpm_write, fnc, sock,
- &fnc->t_write);
+ event_add_read(fnc->fthread->master, fpm_read, fnc, sock,
+ &fnc->t_read);
+ event_add_write(fnc->fthread->master, fpm_write, fnc, sock,
+ &fnc->t_write);
/*
* Starting with LSPs walk all FPM objects, marking them
* If we are not connected, then delay the objects reset/send.
*/
if (!fnc->connecting)
- thread_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0,
- &fnc->t_lspreset);
+ event_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0,
+ &fnc->t_lspreset);
}
/**
memory_order_relaxed);
/* Tell the thread to start writing. */
- thread_add_write(fnc->fthread->master, fpm_write, fnc, fnc->socket,
- &fnc->t_write);
+ event_add_write(fnc->fthread->master, fpm_write, fnc, fnc->socket,
+ &fnc->t_write);
return 0;
}
return HASHWALK_CONTINUE;
}
-static void fpm_lsp_send(struct thread *t)
+static void fpm_lsp_send(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
- struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
struct fpm_lsp_arg fla;
fla.fnc = fnc;
WALK_FINISH(fnc, FNE_LSP_FINISHED);
/* Now move onto routes */
- thread_add_timer(zrouter.master, fpm_nhg_reset, fnc, 0,
- &fnc->t_nhgreset);
+ event_add_timer(zrouter.master, fpm_nhg_reset, fnc, 0,
+ &fnc->t_nhgreset);
} else {
/* Didn't finish - reschedule LSP walk */
- thread_add_timer(zrouter.master, fpm_lsp_send, fnc, 0,
- &fnc->t_lspwalk);
+ event_add_timer(zrouter.master, fpm_lsp_send, fnc, 0,
+ &fnc->t_lspwalk);
}
}
return HASHWALK_CONTINUE;
}
-static void fpm_nhg_send(struct thread *t)
+static void fpm_nhg_send(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
struct fpm_nhg_arg fna;
fna.fnc = fnc;
/* We are done sending next hops, lets install the routes now. */
if (fna.complete) {
WALK_FINISH(fnc, FNE_NHG_FINISHED);
- thread_add_timer(zrouter.master, fpm_rib_reset, fnc, 0,
- &fnc->t_ribreset);
+ event_add_timer(zrouter.master, fpm_rib_reset, fnc, 0,
+ &fnc->t_ribreset);
} else /* Otherwise reschedule next hop group again. */
- thread_add_timer(zrouter.master, fpm_nhg_send, fnc, 0,
- &fnc->t_nhgwalk);
+ event_add_timer(zrouter.master, fpm_nhg_send, fnc, 0,
+ &fnc->t_nhgwalk);
}
/**
* Send all RIB installed routes to the connected data plane.
*/
-static void fpm_rib_send(struct thread *t)
+static void fpm_rib_send(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
rib_dest_t *dest;
struct route_node *rn;
struct route_table *rt;
/* Free the temporary allocated context. */
dplane_ctx_fini(&ctx);
- thread_add_timer(zrouter.master, fpm_rib_send,
- fnc, 1, &fnc->t_ribwalk);
+ event_add_timer(zrouter.master, fpm_rib_send,
+ fnc, 1, &fnc->t_ribwalk);
return;
}
WALK_FINISH(fnc, FNE_RIB_FINISHED);
/* Schedule next event: RMAC reset. */
- thread_add_event(zrouter.master, fpm_rmac_reset, fnc, 0,
- &fnc->t_rmacreset);
+ event_add_event(zrouter.master, fpm_rmac_reset, fnc, 0,
+ &fnc->t_rmacreset);
}
/*
zrmac->fwd_info.r_vtep_ip, sticky, 0 /*nhg*/,
0 /*update_flags*/);
if (fpm_nl_enqueue(fra->fnc, fra->ctx) == -1) {
- thread_add_timer(zrouter.master, fpm_rmac_send,
- fra->fnc, 1, &fra->fnc->t_rmacwalk);
+ event_add_timer(zrouter.master, fpm_rmac_send, fra->fnc, 1,
+ &fra->fnc->t_rmacwalk);
fra->complete = false;
}
}
hash_iterate(zl3vni->rmac_table, fpm_enqueue_rmac_table, zl3vni);
}
-static void fpm_rmac_send(struct thread *t)
+static void fpm_rmac_send(struct event *t)
{
struct fpm_rmac_arg fra;
- fra.fnc = THREAD_ARG(t);
+ fra.fnc = EVENT_ARG(t);
fra.ctx = dplane_ctx_alloc();
fra.complete = true;
hash_iterate(zrouter.l3vni_table, fpm_enqueue_l3vni_table, &fra);
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_FPM);
}
-static void fpm_nhg_reset(struct thread *t)
+static void fpm_nhg_reset(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
hash_iterate(zrouter.nhgs_id, fpm_nhg_reset_cb, NULL);
/* Schedule next step: send next hop groups. */
- thread_add_event(zrouter.master, fpm_nhg_send, fnc, 0, &fnc->t_nhgwalk);
+ event_add_event(zrouter.master, fpm_nhg_send, fnc, 0, &fnc->t_nhgwalk);
}
/*
UNSET_FLAG(lsp->flags, LSP_FLAG_FPM);
}
-static void fpm_lsp_reset(struct thread *t)
+static void fpm_lsp_reset(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
- struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
hash_iterate(zvrf->lsp_table, fpm_lsp_reset_cb, NULL);
/* Schedule next step: send LSPs */
- thread_add_event(zrouter.master, fpm_lsp_send, fnc, 0, &fnc->t_lspwalk);
+ event_add_event(zrouter.master, fpm_lsp_send, fnc, 0, &fnc->t_lspwalk);
}
/**
* Resets the RIB FPM flags so we send all routes again.
*/
-static void fpm_rib_reset(struct thread *t)
+static void fpm_rib_reset(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
rib_dest_t *dest;
struct route_node *rn;
struct route_table *rt;
}
/* Schedule next step: send RIB routes. */
- thread_add_event(zrouter.master, fpm_rib_send, fnc, 0, &fnc->t_ribwalk);
+ event_add_event(zrouter.master, fpm_rib_send, fnc, 0, &fnc->t_ribwalk);
}
/*
hash_iterate(zl3vni->rmac_table, fpm_unset_rmac_table, zl3vni);
}
-static void fpm_rmac_reset(struct thread *t)
+static void fpm_rmac_reset(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
hash_iterate(zrouter.l3vni_table, fpm_unset_l3vni_table, NULL);
/* Schedule next event: send RMAC entries. */
- thread_add_event(zrouter.master, fpm_rmac_send, fnc, 0,
- &fnc->t_rmacwalk);
+ event_add_event(zrouter.master, fpm_rmac_send, fnc, 0,
+ &fnc->t_rmacwalk);
}
-static void fpm_process_queue(struct thread *t)
+static void fpm_process_queue(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
struct zebra_dplane_ctx *ctx;
bool no_bufs = false;
uint64_t processed_contexts = 0;
/* Re-schedule if we ran out of buffer space */
if (no_bufs)
- thread_add_timer(fnc->fthread->master, fpm_process_queue,
- fnc, 0, &fnc->t_dequeue);
+ event_add_timer(fnc->fthread->master, fpm_process_queue, fnc, 0,
+ &fnc->t_dequeue);
/*
* Let the dataplane thread know if there are items in the
/**
* Handles external (e.g. CLI, data plane or others) events.
*/
-static void fpm_process_event(struct thread *t)
+static void fpm_process_event(struct event *t)
{
- struct fpm_nl_ctx *fnc = THREAD_ARG(t);
- enum fpm_nl_events event = THREAD_VAL(t);
+ struct fpm_nl_ctx *fnc = EVENT_ARG(t);
+ enum fpm_nl_events event = EVENT_VAL(t);
switch (event) {
case FNE_DISABLE:
static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc)
{
/* Disable all events and close socket. */
- THREAD_OFF(fnc->t_lspreset);
- THREAD_OFF(fnc->t_lspwalk);
- THREAD_OFF(fnc->t_nhgreset);
- THREAD_OFF(fnc->t_nhgwalk);
- THREAD_OFF(fnc->t_ribreset);
- THREAD_OFF(fnc->t_ribwalk);
- THREAD_OFF(fnc->t_rmacreset);
- THREAD_OFF(fnc->t_rmacwalk);
- THREAD_OFF(fnc->t_event);
- THREAD_OFF(fnc->t_nhg);
- thread_cancel_async(fnc->fthread->master, &fnc->t_read, NULL);
- thread_cancel_async(fnc->fthread->master, &fnc->t_write, NULL);
- thread_cancel_async(fnc->fthread->master, &fnc->t_connect, NULL);
+ EVENT_OFF(fnc->t_lspreset);
+ EVENT_OFF(fnc->t_lspwalk);
+ EVENT_OFF(fnc->t_nhgreset);
+ EVENT_OFF(fnc->t_nhgwalk);
+ EVENT_OFF(fnc->t_ribreset);
+ EVENT_OFF(fnc->t_ribwalk);
+ EVENT_OFF(fnc->t_rmacreset);
+ EVENT_OFF(fnc->t_rmacwalk);
+ EVENT_OFF(fnc->t_event);
+ EVENT_OFF(fnc->t_nhg);
+ event_cancel_async(fnc->fthread->master, &fnc->t_read, NULL);
+ event_cancel_async(fnc->fthread->master, &fnc->t_write, NULL);
+ event_cancel_async(fnc->fthread->master, &fnc->t_connect, NULL);
if (fnc->socket != -1) {
close(fnc->socket);
if (atomic_load_explicit(&fnc->counters.ctxqueue_len,
memory_order_relaxed)
> 0)
- thread_add_timer(fnc->fthread->master, fpm_process_queue,
- fnc, 0, &fnc->t_dequeue);
+ event_add_timer(fnc->fthread->master, fpm_process_queue, fnc, 0,
+ &fnc->t_dequeue);
/* Ensure dataplane thread is rescheduled if we hit the work limit */
if (counter >= limit)
return 0;
}
-static int fpm_nl_new(struct thread_master *tm)
+static int fpm_nl_new(struct event_loop *tm)
{
struct zebra_dplane_provider *prov = NULL;
int rv;
#include "table.h"
#include "memory.h"
#include "rib.h"
-#include "thread.h"
+#include "frrevent.h"
#include "privs.h"
#include "nexthop.h"
#include "vrf.h"
static void if_down_del_nbr_connected(struct interface *ifp);
-static void if_zebra_speed_update(struct thread *thread)
+static void if_zebra_speed_update(struct event *thread)
{
- struct interface *ifp = THREAD_ARG(thread);
+ struct interface *ifp = EVENT_ARG(thread);
struct zebra_if *zif = ifp->info;
uint32_t new_speed;
bool changed = false;
return;
zif->speed_update_count++;
- thread_add_timer(zrouter.master, if_zebra_speed_update, ifp,
- SPEED_UPDATE_SLEEP_TIME, &zif->speed_update);
- thread_ignore_late_timer(zif->speed_update);
+ event_add_timer(zrouter.master, if_zebra_speed_update, ifp,
+ SPEED_UPDATE_SLEEP_TIME, &zif->speed_update);
+ event_ignore_late_timer(zif->speed_update);
}
}
* down upon startup.
*/
zebra_if->speed_update_count = 0;
- thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
- &zebra_if->speed_update);
- thread_ignore_late_timer(zebra_if->speed_update);
+ event_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
+ &zebra_if->speed_update);
+ event_ignore_late_timer(zebra_if->speed_update);
return 0;
}
XFREE(MTYPE_ZIF_DESC, zebra_if->desc);
- THREAD_OFF(zebra_if->speed_update);
+ EVENT_OFF(zebra_if->speed_update);
XFREE(MTYPE_ZINFO, zebra_if);
}
if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
zebra_evpn_mh_uplink_oper_update(zif);
- thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
- &zif->speed_update);
- thread_ignore_late_timer(zif->speed_update);
+ event_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
+ &zif->speed_update);
+ event_ignore_late_timer(zif->speed_update);
}
/* Interface goes down. We have to manage different behavior of based
struct interface *link;
uint8_t speed_update_count;
- struct thread *speed_update;
+ struct event *speed_update;
/*
* Does this interface have a v6 to v4 ll neighbor entry
#define IF_SHUTDOWN (1<<6)
struct interface *ifp;
- struct thread *t_advertise;
+ struct event *t_advertise;
unsigned long irdp_sent;
uint16_t Lifetime;
extern void irdp_if_init(void);
extern int irdp_sock_init(void);
extern int irdp_config_write(struct vty *, struct interface *);
-extern void irdp_send_thread(struct thread *t_advert);
+extern void irdp_send_thread(struct event *t_advert);
extern void irdp_advert_off(struct interface *ifp);
extern void process_solicit(struct interface *ifp);
-extern void irdp_read_raw(struct thread *r);
+extern void irdp_read_raw(struct event *r);
extern void send_packet(struct interface *ifp, struct stream *s, uint32_t dst,
struct prefix *p, uint32_t ttl);
#include "connected.h"
#include "log.h"
#include "zclient.h"
-#include "thread.h"
+#include "frrevent.h"
#include "lib_errors.h"
#include "zebra/interface.h"
#include "zebra/rtadv.h"
timer);
irdp->t_advertise = NULL;
- thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
- &irdp->t_advertise);
+ event_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
+ &irdp->t_advertise);
}
static void irdp_if_stop(struct interface *ifp)
#include "connected.h"
#include "log.h"
#include "zclient.h"
-#include "thread.h"
+#include "frrevent.h"
#include "privs.h"
#include "libfrr.h"
#include "lib_errors.h"
extern struct zebra_privs_t zserv_privs;
-struct thread *t_irdp_raw;
+struct event *t_irdp_raw;
/* Timer interval of irdp. */
int irdp_timer_interval = IRDP_DEFAULT_INTERVAL;
return ret;
};
- thread_add_read(zrouter.master, irdp_read_raw, NULL, sock, &t_irdp_raw);
+ event_add_read(zrouter.master, irdp_read_raw, NULL, sock, &t_irdp_raw);
return sock;
}
stream_free(s);
}
-void irdp_send_thread(struct thread *t_advert)
+void irdp_send_thread(struct event *t_advert)
{
uint32_t timer, tmp;
- struct interface *ifp = THREAD_ARG(t_advert);
+ struct interface *ifp = EVENT_ARG(t_advert);
struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = zi->irdp;
struct prefix *p;
timer);
irdp->t_advertise = NULL;
- thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
- &irdp->t_advertise);
+ event_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
+ &irdp->t_advertise);
}
void irdp_advert_off(struct interface *ifp)
if (!irdp)
return;
- THREAD_OFF(irdp->t_advertise);
+ EVENT_OFF(irdp->t_advertise);
if (ifp->connected)
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
return;
irdp->flags |= IF_SOLICIT;
- THREAD_OFF(irdp->t_advertise);
+ EVENT_OFF(irdp->t_advertise);
timer = (frr_weak_random() % MAX_RESPONSE_DELAY) + 1;
irdp->t_advertise = NULL;
- thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
- &irdp->t_advertise);
+ event_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
+ &irdp->t_advertise);
}
static int irdp_finish(void)
return 0;
}
-static int irdp_init(struct thread_master *master)
+static int irdp_init(struct event_loop *master)
{
irdp_if_init();
#include "sockunion.h"
#include "sockunion.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vty.h"
#include "zclient.h"
#include "lib_errors.h"
int irdp_sock = -1;
-extern struct thread *t_irdp_raw;
+extern struct event *t_irdp_raw;
static void parse_irdp_packet(char *p, int len, struct interface *ifp)
{
return ret;
}
-void irdp_read_raw(struct thread *r)
+void irdp_read_raw(struct event *r)
{
struct interface *ifp;
struct zebra_if *zi;
char buf[IRDP_RX_BUF];
int ret, ifindex = 0;
- int irdp_sock = THREAD_FD(r);
- thread_add_read(zrouter.master, irdp_read_raw, NULL, irdp_sock,
- &t_irdp_raw);
+ int irdp_sock = EVENT_FD(r);
+ event_add_read(zrouter.master, irdp_read_raw, NULL, irdp_sock,
+ &t_irdp_raw);
ret = irdp_recvmsg(irdp_sock, (uint8_t *)buf, IRDP_RX_BUF, &ifindex);
#include "table.h"
#include "memory.h"
#include "rib.h"
-#include "thread.h"
+#include "frrevent.h"
#include "privs.h"
#include "nexthop.h"
#include "vrf.h"
{RTN_XRESOLVE, "resolver"},
{0}};
-extern struct thread_master *master;
+extern struct event_loop *master;
extern struct zebra_privs_t zserv_privs;
return 0;
}
-static void kernel_read(struct thread *thread)
+static void kernel_read(struct event *thread)
{
- struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread);
+ struct zebra_ns *zns = (struct zebra_ns *)EVENT_ARG(thread);
struct zebra_dplane_info dp_info;
/* Capture key info from ns struct */
netlink_parse_info(netlink_information_fetch, &zns->netlink, &dp_info,
5, false);
- thread_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock,
- &zns->t_netlink);
+ event_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock,
+ &zns->t_netlink);
}
/*
zns->t_netlink = NULL;
- thread_add_read(zrouter.master, kernel_read, zns,
- zns->netlink.sock, &zns->t_netlink);
+ event_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock,
+ &zns->t_netlink);
rt_netlink_init();
}
void kernel_terminate(struct zebra_ns *zns, bool complete)
{
- THREAD_OFF(zns->t_netlink);
+ EVENT_OFF(zns->t_netlink);
kernel_nlsock_fini(&zns->netlink);
}
-#include "thread.h"
+#include "frrevent.h"
#include "zebra/zserv.h"
/* For debug purpose. */
#endif /* RTAX_MAX */
/* Kernel routing table and interface updates via routing socket. */
-static void kernel_read(struct thread *thread)
+static void kernel_read(struct event *thread)
{
int sock;
int nbytes;
} buf;
/* Fetch routing socket. */
- sock = THREAD_FD(thread);
+ sock = EVENT_FD(thread);
nbytes = read(sock, &buf, sizeof(buf));
* shortage and is not harmful for consistency of
* reading the routing socket. Ignore it.
*/
- thread_add_read(zrouter.master, kernel_read, NULL, sock,
- NULL);
+ event_add_read(zrouter.master, kernel_read, NULL, sock,
+ NULL);
return;
#else
flog_err(EC_ZEBRA_RECVMSG_OVERRUN,
if (nbytes == 0)
return;
- thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL);
+ event_add_read(zrouter.master, kernel_read, NULL, sock, NULL);
if (IS_ZEBRA_DEBUG_KERNEL)
rtmsg_debug(&buf.r.rtm);
}
/* kernel_read needs rewrite. */
- thread_add_read(zrouter.master, kernel_read, NULL, routing_sock, NULL);
+ event_add_read(zrouter.master, kernel_read, NULL, routing_sock, NULL);
}
/* Exported interface function. This function simply calls
#include <stdint.h>
#include "lib/linklist.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/hook.h"
#include "zebra/zserv.h"
#include <lib/version.h>
#include "getopt.h"
#include "command.h"
-#include "thread.h"
+#include "frrevent.h"
#include "filter.h"
#include "memory.h"
#include "prefix.h"
pid_t pid;
/* Pacify zclient.o in libfrr, which expects this variable. */
-struct thread_master *master;
+struct event_loop *master;
/* Route retain mode flag. */
int retain_mode = 0;
if (zrouter.lsp_process_q)
work_queue_free_and_null(&zrouter.lsp_process_q);
- vrf_terminate();
-
- ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
- zebra_ns_notify_close();
-
access_list_reset();
prefix_list_reset();
/*
*/
zebra_routemap_finish();
+ rib_update_finish();
+
list_delete(&zrouter.client_list);
/* Indicate that all new dplane work has been enqueued. When that
* Final shutdown step for the zebra main thread. This is run after all
* async update processing has completed.
*/
-void zebra_finalize(struct thread *dummy)
+void zebra_finalize(struct event *dummy)
{
zlog_info("Zebra final shutdown");
+ vrf_terminate();
+
+ ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
+ zebra_ns_notify_close();
+
/* Stop dplane thread and finish any cleanup */
zebra_dplane_shutdown();
* we have to have route_read() called before.
*/
zrouter.startup_time = monotime(NULL);
- thread_add_timer(zrouter.master, rib_sweep_route, NULL,
- graceful_restart, &zrouter.sweeper);
+ event_add_timer(zrouter.master, rib_sweep_route, NULL, graceful_restart,
+ &zrouter.sweeper);
/* Needed for BSD routing socket. */
pid = getpid();
return false;
afi = family2afi(rn->p.family);
- zvrf = vrf_info_lookup(re->vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
if (re->vrf_id == VRF_DEFAULT && zvrf->table_id != re->table)
return false;
RIB_UPDATE_OTHER,
RIB_UPDATE_MAX
};
+void rib_update_finish(void);
int route_entry_update_nhe(struct route_entry *re,
struct nhg_hash_entry *new_nhghe);
extern void rib_update(enum rib_update_event event);
extern void rib_update_table(struct route_table *table,
enum rib_update_event event, int rtype);
-extern void rib_sweep_route(struct thread *t);
+extern void rib_sweep_route(struct event *t);
extern void rib_sweep_table(struct route_table *table);
extern void rib_close_table(struct route_table *table);
extern void rib_init(void);
argv_find(argv, argc, "NAME", &idx);
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
- zvrf = vrf_info_lookup(vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS;
argv_find(argv, argc, "NAME", &idx);
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
- zvrf = vrf_info_lookup(vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
router_id_set(AFI_IP6, &rid, zvrf);
return CMD_SUCCESS;
if (argv_find(argv, argc, "NAME", &idx))
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
- zvrf = vrf_info_lookup(vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
router_id_set(AFI_IP, &rid, zvrf);
return CMD_SUCCESS;
if (argv_find(argv, argc, "NAME", &idx))
VRF_GET_ID(vrf_id, argv[idx]->arg, false);
- zvrf = vrf_info_lookup(vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
router_id_set(AFI_IP6, &rid, zvrf);
return CMD_SUCCESS;
vrf_name = argv[idx]->arg;
}
- zvrf = vrf_info_lookup(vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
if (zvrf != NULL) {
if (is_ipv6) {
#include "table.h"
#include "memory.h"
#include "rib.h"
-#include "thread.h"
+#include "frrevent.h"
#include "privs.h"
#include "nexthop.h"
#include "vrf.h"
#include "memory.h"
#include "sockopt.h"
-#include "thread.h"
+#include "frrevent.h"
#include "if.h"
#include "stream.h"
#include "log.h"
zif->ra_sent++;
}
-static void rtadv_timer(struct thread *thread)
+static void rtadv_timer(struct event *thread)
{
- struct zebra_vrf *zvrf = THREAD_ARG(thread);
+ struct zebra_vrf *zvrf = EVENT_ARG(thread);
struct vrf *vrf;
struct interface *ifp;
struct zebra_if *zif;
return;
}
-static void rtadv_read(struct thread *thread)
+static void rtadv_read(struct event *thread)
{
int sock;
int len;
struct sockaddr_in6 from;
ifindex_t ifindex = 0;
int hoplimit = -1;
- struct zebra_vrf *zvrf = THREAD_ARG(thread);
+ struct zebra_vrf *zvrf = EVENT_ARG(thread);
- sock = THREAD_FD(thread);
+ sock = EVENT_FD(thread);
zvrf->rtadv.ra_read = NULL;
/* Register myself. */
switch (event) {
case RTADV_START:
- thread_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
- &rtadv->ra_read);
- thread_add_event(zrouter.master, rtadv_timer, zvrf, 0,
- &rtadv->ra_timer);
+ event_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
+ &rtadv->ra_read);
+ event_add_event(zrouter.master, rtadv_timer, zvrf, 0,
+ &rtadv->ra_timer);
break;
case RTADV_STOP:
- THREAD_OFF(rtadv->ra_timer);
- THREAD_OFF(rtadv->ra_read);
+ EVENT_OFF(rtadv->ra_timer);
+ EVENT_OFF(rtadv->ra_read);
break;
case RTADV_TIMER:
- thread_add_timer(zrouter.master, rtadv_timer, zvrf, val,
- &rtadv->ra_timer);
+ event_add_timer(zrouter.master, rtadv_timer, zvrf, val,
+ &rtadv->ra_timer);
break;
case RTADV_TIMER_MSEC:
- thread_add_timer_msec(zrouter.master, rtadv_timer, zvrf, val,
- &rtadv->ra_timer);
+ event_add_timer_msec(zrouter.master, rtadv_timer, zvrf, val,
+ &rtadv->ra_timer);
break;
case RTADV_READ:
- thread_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
- &rtadv->ra_read);
+ event_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
+ &rtadv->ra_read);
break;
default:
break;
struct adv_if_list_head adv_if;
struct adv_if_list_head adv_msec_if;
- struct thread *ra_read;
- struct thread *ra_timer;
+ struct event *ra_read;
+ struct event *ra_timer;
};
PREDECL_RBTREE_UNIQ(rtadv_prefixes);
* Init entry point called during zebra startup. This is registered during
* module init.
*/
-static int init_sample_plugin(struct thread_master *tm)
+static int init_sample_plugin(struct event_loop *tm)
{
int ret;
#include <stdint.h>
#include "lib/linklist.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/ns.h"
#include "zebra/zserv.h"
uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
s = msg;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return;
uint16_t flags;
s = msg;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return;
struct zebra_vrf *zvrf;
struct zserv *client;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
/* Do not send unsolicited messages to synchronous clients. */
if (client->synchronous)
struct zebra_dplane_info info;
/* Request data from the OS */
- struct thread *t_request;
+ struct event *t_request;
/* Read event */
- struct thread *t_read;
+ struct event *t_read;
/* List linkage */
struct zns_info_list_item link;
struct frr_pthread *dg_pthread;
/* Event-delivery context 'master' for the dplane */
- struct thread_master *dg_master;
+ struct event_loop *dg_master;
/* Event/'thread' pointer for queued updates */
- struct thread *dg_t_update;
+ struct event *dg_t_update;
/* Event pointer for pending shutdown check loop */
- struct thread *dg_t_shutdown_check;
+ struct event *dg_t_shutdown_check;
} zdplane_info;
#define DPLANE_PROV_UNLOCK(p) pthread_mutex_unlock(&((p)->dp_mutex))
/* Prototypes */
-static void dplane_thread_loop(struct thread *event);
+static void dplane_thread_loop(struct event *event);
static enum zebra_dplane_result lsp_update_internal(struct zebra_lsp *lsp,
enum dplane_op_e op);
static enum zebra_dplane_result pw_update_internal(struct zebra_pw *pw,
*/
/* Obtain thread_master for dataplane thread */
-struct thread_master *dplane_get_thread_master(void)
+struct event_loop *dplane_get_thread_master(void)
{
return zdplane_info.dg_master;
}
* Callback when an OS (netlink) incoming event read is ready. This runs
* in the dplane pthread.
*/
-static void dplane_incoming_read(struct thread *event)
+static void dplane_incoming_read(struct event *event)
{
- struct dplane_zns_info *zi = THREAD_ARG(event);
+ struct dplane_zns_info *zi = EVENT_ARG(event);
kernel_dplane_read(&zi->info);
/* Re-start read task */
- thread_add_read(zdplane_info.dg_master, dplane_incoming_read, zi,
- zi->info.sock, &zi->t_read);
+ event_add_read(zdplane_info.dg_master, dplane_incoming_read, zi,
+ zi->info.sock, &zi->t_read);
}
/*
* Callback in the dataplane pthread that requests info from the OS and
* initiates netlink reads.
*/
-static void dplane_incoming_request(struct thread *event)
+static void dplane_incoming_request(struct event *event)
{
- struct dplane_zns_info *zi = THREAD_ARG(event);
+ struct dplane_zns_info *zi = EVENT_ARG(event);
/* Start read task */
- thread_add_read(zdplane_info.dg_master, dplane_incoming_read, zi,
- zi->info.sock, &zi->t_read);
+ event_add_read(zdplane_info.dg_master, dplane_incoming_read, zi,
+ zi->info.sock, &zi->t_read);
/* Send requests */
netlink_request_netconf(zi->info.sock);
* pthread is running, we'll initiate this later on.
*/
if (zdplane_info.dg_master)
- thread_add_event(zdplane_info.dg_master,
- dplane_incoming_request, zi, 0,
- &zi->t_request);
+ event_add_event(zdplane_info.dg_master, dplane_incoming_request,
+ zi, 0, &zi->t_request);
}
#endif /* HAVE_NETLINK */
/* Stop any outstanding tasks */
if (zdplane_info.dg_master) {
- thread_cancel_async(zdplane_info.dg_master,
- &zi->t_request, NULL);
+ event_cancel_async(zdplane_info.dg_master,
+ &zi->t_request, NULL);
- thread_cancel_async(zdplane_info.dg_master, &zi->t_read,
- NULL);
+ event_cancel_async(zdplane_info.dg_master, &zi->t_read,
+ NULL);
}
XFREE(MTYPE_DP_NS, zi);
* available.
*/
if (zdplane_info.dg_run) {
- thread_add_event(zdplane_info.dg_master,
- dplane_thread_loop, NULL, 0,
- &zdplane_info.dg_t_update);
+ event_add_event(zdplane_info.dg_master, dplane_thread_loop,
+ NULL, 0, &zdplane_info.dg_t_update);
}
return AOK;
* final zebra shutdown.
* This runs in the dplane pthread context.
*/
-static void dplane_check_shutdown_status(struct thread *event)
+static void dplane_check_shutdown_status(struct event *event)
{
struct dplane_zns_info *zi;
zns_info_list_del(&zdplane_info.dg_zns_list, zi);
if (zdplane_info.dg_master) {
- THREAD_OFF(zi->t_read);
- THREAD_OFF(zi->t_request);
+ EVENT_OFF(zi->t_read);
+ EVENT_OFF(zi->t_request);
}
XFREE(MTYPE_DP_NS, zi);
if (dplane_work_pending()) {
/* Reschedule dplane check on a short timer */
- thread_add_timer_msec(zdplane_info.dg_master,
- dplane_check_shutdown_status,
- NULL, 100,
- &zdplane_info.dg_t_shutdown_check);
+ event_add_timer_msec(zdplane_info.dg_master,
+ dplane_check_shutdown_status, NULL, 100,
+ &zdplane_info.dg_t_shutdown_check);
/* TODO - give up and stop waiting after a short time? */
/* We appear to be done - schedule a final callback event
* for the zebra main pthread.
*/
- thread_add_event(zrouter.master, zebra_finalize, NULL, 0, NULL);
+ event_add_event(zrouter.master, zebra_finalize, NULL, 0, NULL);
}
}
if (IS_ZEBRA_DEBUG_DPLANE)
zlog_debug("Zebra dataplane fini called");
- thread_add_event(zdplane_info.dg_master,
- dplane_check_shutdown_status, NULL, 0,
- &zdplane_info.dg_t_shutdown_check);
+ event_add_event(zdplane_info.dg_master, dplane_check_shutdown_status,
+ NULL, 0, &zdplane_info.dg_t_shutdown_check);
}
/*
* pthread can look for other pending work - such as i/o work on behalf of
* providers.
*/
-static void dplane_thread_loop(struct thread *event)
+static void dplane_thread_loop(struct event *event)
{
struct dplane_ctx_list_head work_list;
struct dplane_ctx_list_head error_list;
zdplane_info.dg_run = false;
if (zdplane_info.dg_t_update)
- thread_cancel_async(zdplane_info.dg_t_update->master,
- &zdplane_info.dg_t_update, NULL);
+ event_cancel_async(zdplane_info.dg_t_update->master,
+ &zdplane_info.dg_t_update, NULL);
frr_pthread_stop(zdplane_info.dg_pthread, NULL);
zdplane_info.dg_run = true;
/* Enqueue an initial event for the dataplane pthread */
- thread_add_event(zdplane_info.dg_master, dplane_thread_loop, NULL, 0,
- &zdplane_info.dg_t_update);
+ event_add_event(zdplane_info.dg_master, dplane_thread_loop, NULL, 0,
+ &zdplane_info.dg_t_update);
/* Enqueue requests and reads if necessary */
frr_each (zns_info_list, &zdplane_info.dg_zns_list, zi) {
#if defined(HAVE_NETLINK)
- thread_add_read(zdplane_info.dg_master, dplane_incoming_read,
- zi, zi->info.sock, &zi->t_read);
+ event_add_read(zdplane_info.dg_master, dplane_incoming_read, zi,
+ zi->info.sock, &zi->t_read);
dplane_kernel_info_request(zi);
#endif
}
void dplane_provider_unlock(struct zebra_dplane_provider *prov);
/* Obtain thread_master for dataplane thread */
-struct thread_master *dplane_get_thread_master(void);
+struct event_loop *dplane_get_thread_master(void);
/* Providers should (generally) limit number of updates per work cycle */
int dplane_provider_get_work_limit(const struct zebra_dplane_provider *prov);
return buf;
}
-static void zebra_evpn_dad_mac_auto_recovery_exp(struct thread *t)
+static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t)
{
struct zebra_vrf *zvrf = NULL;
struct zebra_mac *mac = NULL;
struct listnode *node = NULL;
struct zebra_neigh *nbr = NULL;
- mac = THREAD_ARG(t);
+ mac = EVENT_ARG(t);
/* since this is asynchronous we need sanity checks*/
- zvrf = vrf_info_lookup(mac->zevpn->vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(mac->zevpn->vrf_id);
if (!zvrf)
return;
}
/* Start auto recovery timer for this MAC */
- THREAD_OFF(mac->dad_mac_auto_recovery_timer);
+ EVENT_OFF(mac->dad_mac_auto_recovery_timer);
if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
if (IS_ZEBRA_DEBUG_VXLAN) {
char mac_buf[MAC_BUF_SIZE];
zvrf->dad_freeze_time);
}
- thread_add_timer(zrouter.master,
- zebra_evpn_dad_mac_auto_recovery_exp,
- mac, zvrf->dad_freeze_time,
- &mac->dad_mac_auto_recovery_timer);
+ event_add_timer(zrouter.master,
+ zebra_evpn_dad_mac_auto_recovery_exp,
+ mac, zvrf->dad_freeze_time,
+ &mac->dad_mac_auto_recovery_timer);
}
/* In case of local update, do not inform to client (BGPd),
struct zebra_vrf *zvrf;
struct timeval detect_start_time = {0, 0};
char timebuf[MONOTIME_STRLEN];
- char thread_buf[THREAD_TIMER_STRLEN];
+ char thread_buf[EVENT_TIMER_STRLEN];
time_t uptime;
char up_str[MONOTIME_STRLEN];
if (mac->hold_timer)
json_object_string_add(
json_mac, "peerActiveHold",
- thread_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- mac->hold_timer));
+ event_timer_to_hhmmss(thread_buf,
+ sizeof(thread_buf),
+ mac->hold_timer));
if (mac->es)
json_object_string_add(json_mac, "esi",
mac->es->esi_str);
vty_out(vty, " peer-active");
if (mac->hold_timer)
vty_out(vty, " (ht: %s)",
- thread_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- mac->hold_timer));
+ event_timer_to_hhmmss(thread_buf,
+ sizeof(thread_buf),
+ mac->hold_timer));
vty_out(vty, "\n");
vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq,
mac->rem_seq);
zebra_evpn_mac_stop_hold_timer(mac);
/* Cancel auto recovery */
- THREAD_OFF(mac->dad_mac_auto_recovery_timer);
+ EVENT_OFF(mac->dad_mac_auto_recovery_timer);
/* If the MAC is freed before the neigh we will end up
* with a stale pointer against the neigh.
* external neighmgr daemon to probe existing hosts to independently
* establish their presence on the ES.
*/
-static void zebra_evpn_mac_hold_exp_cb(struct thread *t)
+static void zebra_evpn_mac_hold_exp_cb(struct event *t)
{
struct zebra_mac *mac;
bool old_bgp_ready;
bool old_static;
bool new_static;
- mac = THREAD_ARG(t);
+ mac = EVENT_ARG(t);
/* the purpose of the hold timer is to age out the peer-active
* flag
*/
zebra_evpn_zebra_mac_flag_dump(mac, mac_buf,
sizeof(mac_buf)));
}
- thread_add_timer(zrouter.master, zebra_evpn_mac_hold_exp_cb, mac,
- zmh_info->mac_hold_time, &mac->hold_timer);
+ event_add_timer(zrouter.master, zebra_evpn_mac_hold_exp_cb, mac,
+ zmh_info->mac_hold_time, &mac->hold_timer);
}
void zebra_evpn_mac_stop_hold_timer(struct zebra_mac *mac)
sizeof(mac_buf)));
}
- THREAD_OFF(mac->hold_timer);
+ EVENT_OFF(mac->hold_timer);
}
void zebra_evpn_sync_mac_del(struct zebra_mac *mac)
/* Duplicate mac detection */
uint32_t dad_count;
- struct thread *dad_mac_auto_recovery_timer;
+ struct event *dad_mac_auto_recovery_timer;
struct timeval detect_start_time;
time_t dad_dup_detect_time;
/* used for ageing out the PEER_ACTIVE flag */
- struct thread *hold_timer;
+ struct event *hold_timer;
/* number of neigh entries (using this mac) that have
* ZEBRA_MAC_ES_PEER_ACTIVE or ZEBRA_NEIGH_ES_PEER_PROXY
zebra_evpn_acc_vl_adv_svi_mac_all();
}
-static void zebra_evpn_es_df_delay_exp_cb(struct thread *t)
+static void zebra_evpn_es_df_delay_exp_cb(struct event *t)
{
struct zebra_evpn_es *es;
- es = THREAD_ARG(t);
+ es = EVENT_ARG(t);
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
zlog_debug("es %s df-delay expired", es->esi_str);
/* Start the DF delay timer on the local ES */
if (!es->df_delay_timer)
- thread_add_timer(zrouter.master, zebra_evpn_es_df_delay_exp_cb,
- es, ZEBRA_EVPN_MH_DF_DELAY_TIME,
- &es->df_delay_timer);
+ event_add_timer(zrouter.master, zebra_evpn_es_df_delay_exp_cb,
+ es, ZEBRA_EVPN_MH_DF_DELAY_TIME,
+ &es->df_delay_timer);
/* See if the local VTEP can function as DF on the ES */
if (!zebra_evpn_es_run_df_election(es, __func__)) {
es->flags &= ~(ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_READY_FOR_BGP);
- THREAD_OFF(es->df_delay_timer);
+ EVENT_OFF(es->df_delay_timer);
/* clear EVPN protodown flags on the access port */
zebra_evpn_mh_clear_protodown_es(es);
char alg_buf[EVPN_DF_ALG_STR_LEN];
struct zebra_evpn_es_vtep *es_vtep;
struct listnode *node;
- char thread_buf[THREAD_TIMER_STRLEN];
+ char thread_buf[EVENT_TIMER_STRLEN];
if (json) {
json_object *json_vteps;
if (es->df_delay_timer)
json_object_string_add(
json, "dfDelayTimer",
- thread_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- es->df_delay_timer));
+ event_timer_to_hhmmss(thread_buf,
+ sizeof(thread_buf),
+ es->df_delay_timer));
json_object_int_add(json, "nexthopGroup", es->nhg_id);
if (listcount(es->es_vtep_list)) {
json_vteps = json_object_new_array();
: "df");
if (es->df_delay_timer)
vty_out(vty, " DF delay: %s\n",
- thread_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- es->df_delay_timer));
+ event_timer_to_hhmmss(thread_buf,
+ sizeof(thread_buf),
+ es->df_delay_timer));
vty_out(vty, " DF preference: %u\n", es->df_pref);
vty_out(vty, " Nexthop group: %u\n", es->nhg_id);
vty_out(vty, " VTEPs:\n");
void zebra_evpn_mh_json(json_object *json)
{
json_object *json_array;
- char thread_buf[THREAD_TIMER_STRLEN];
+ char thread_buf[EVENT_TIMER_STRLEN];
json_object_int_add(json, "macHoldtime", zmh_info->mac_hold_time);
json_object_int_add(json, "neighHoldtime", zmh_info->neigh_hold_time);
json_object_int_add(json, "startupDelay", zmh_info->startup_delay_time);
json_object_string_add(
json, "startupDelayTimer",
- thread_timer_to_hhmmss(thread_buf, sizeof(thread_buf),
- zmh_info->startup_delay_timer));
+ event_timer_to_hhmmss(thread_buf, sizeof(thread_buf),
+ zmh_info->startup_delay_timer));
json_object_int_add(json, "uplinkConfigCount",
zmh_info->uplink_cfg_cnt);
json_object_int_add(json, "uplinkActiveCount",
void zebra_evpn_mh_print(struct vty *vty)
{
char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
- char thread_buf[THREAD_TIMER_STRLEN];
+ char thread_buf[EVENT_TIMER_STRLEN];
vty_out(vty, "EVPN MH:\n");
vty_out(vty, " mac-holdtime: %ds, neigh-holdtime: %ds\n",
zmh_info->mac_hold_time, zmh_info->neigh_hold_time);
vty_out(vty, " startup-delay: %ds, start-delay-timer: %s\n",
zmh_info->startup_delay_time,
- thread_timer_to_hhmmss(thread_buf, sizeof(thread_buf),
- zmh_info->startup_delay_timer));
+ event_timer_to_hhmmss(thread_buf, sizeof(thread_buf),
+ zmh_info->startup_delay_timer));
vty_out(vty, " uplink-cfg-cnt: %u, uplink-active-cnt: %u\n",
zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt);
if (zmh_info->protodown_rc)
new_protodown);
}
-static void zebra_evpn_mh_startup_delay_exp_cb(struct thread *t)
+static void zebra_evpn_mh_startup_delay_exp_cb(struct event *t)
{
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
zlog_debug("startup-delay expired");
if (zmh_info->startup_delay_timer) {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
zlog_debug("startup-delay timer cancelled");
- THREAD_OFF(zmh_info->startup_delay_timer);
+ EVENT_OFF(zmh_info->startup_delay_timer);
}
if (zmh_info->startup_delay_time) {
zlog_debug(
"startup-delay timer started for %d sec on %s",
zmh_info->startup_delay_time, rc);
- thread_add_timer(zrouter.master,
- zebra_evpn_mh_startup_delay_exp_cb, NULL,
- zmh_info->startup_delay_time,
- &zmh_info->startup_delay_timer);
+ event_add_timer(zrouter.master,
+ zebra_evpn_mh_startup_delay_exp_cb, NULL,
+ zmh_info->startup_delay_time,
+ &zmh_info->startup_delay_timer);
zebra_evpn_mh_update_protodown(
ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY, true /* set */);
} else {
* imported before running the DF election.
*/
#define ZEBRA_EVPN_MH_DF_DELAY_TIME 3 /* seconds */
- struct thread *df_delay_timer;
+ struct event *df_delay_timer;
};
RB_HEAD(zebra_es_rb_head, zebra_evpn_es);
RB_PROTOTYPE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp);
*/
int startup_delay_time; /* seconds */
#define ZEBRA_EVPN_MH_STARTUP_DELAY_DEF (3 * 60)
- struct thread *startup_delay_timer;
+ struct event *startup_delay_timer;
/* Number of configured uplinks */
uint32_t uplink_cfg_cnt;
* external neighmgr daemon to probe existing hosts to independently
* establish their presence on the ES.
*/
-static void zebra_evpn_neigh_hold_exp_cb(struct thread *t)
+static void zebra_evpn_neigh_hold_exp_cb(struct event *t)
{
struct zebra_neigh *n;
bool old_bgp_ready;
bool old_n_static;
bool new_n_static;
- n = THREAD_ARG(t);
+ n = EVENT_ARG(t);
/* the purpose of the hold timer is to age out the peer-active
* flag
*/
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
zlog_debug("sync-neigh vni %u ip %pIA mac %pEA 0x%x hold start",
n->zevpn->vni, &n->ip, &n->emac, n->flags);
- thread_add_timer(zrouter.master, zebra_evpn_neigh_hold_exp_cb, n,
- zmh_info->neigh_hold_time, &n->hold_timer);
+ event_add_timer(zrouter.master, zebra_evpn_neigh_hold_exp_cb, n,
+ zmh_info->neigh_hold_time, &n->hold_timer);
}
static void zebra_evpn_local_neigh_deref_mac(struct zebra_neigh *n,
listnode_delete(n->mac->neigh_list, n);
/* Cancel auto recovery */
- THREAD_OFF(n->dad_ip_auto_recovery_timer);
+ EVENT_OFF(n->dad_ip_auto_recovery_timer);
/* Cancel proxy hold timer */
zebra_evpn_neigh_stop_hold_timer(n);
return 0;
}
-static void zebra_evpn_dad_ip_auto_recovery_exp(struct thread *t)
+static void zebra_evpn_dad_ip_auto_recovery_exp(struct event *t)
{
struct zebra_vrf *zvrf = NULL;
struct zebra_neigh *nbr = NULL;
struct zebra_evpn *zevpn = NULL;
- nbr = THREAD_ARG(t);
+ nbr = EVENT_ARG(t);
/* since this is asynchronous we need sanity checks*/
zvrf = vrf_info_lookup(nbr->zevpn->vrf_id);
nbr->dad_dup_detect_time = monotime(NULL);
/* Start auto recovery timer for this IP */
- THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
+ EVENT_OFF(nbr->dad_ip_auto_recovery_timer);
if (zvrf->dad_freeze && zvrf->dad_freeze_time) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
__func__, &nbr->emac, &nbr->ip,
nbr->flags, zvrf->dad_freeze_time);
- thread_add_timer(zrouter.master,
- zebra_evpn_dad_ip_auto_recovery_exp,
- nbr, zvrf->dad_freeze_time,
- &nbr->dad_ip_auto_recovery_timer);
+ event_add_timer(zrouter.master,
+ zebra_evpn_dad_ip_auto_recovery_exp,
+ nbr, zvrf->dad_freeze_time,
+ &nbr->dad_ip_auto_recovery_timer);
}
if (zvrf->dad_freeze)
*is_dup_detect = true;
nbr->detect_start_time.tv_sec = 0;
nbr->detect_start_time.tv_usec = 0;
nbr->dad_dup_detect_time = 0;
- THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
+ EVENT_OFF(nbr->dad_ip_auto_recovery_timer);
if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
zebra_evpn_neigh_send_add_to_client(zevpn->vni, &nbr->ip,
struct zebra_vrf *zvrf = NULL;
struct timeval detect_start_time = {0, 0};
char timebuf[MONOTIME_STRLEN];
- char thread_buf[THREAD_TIMER_STRLEN];
+ char thread_buf[EVENT_TIMER_STRLEN];
time_t uptime;
char up_str[MONOTIME_STRLEN];
}
if (n->hold_timer) {
vty_out(vty, " (ht: %s)",
- thread_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- n->hold_timer));
+ event_timer_to_hhmmss(thread_buf,
+ sizeof(thread_buf),
+ n->hold_timer));
sync_info = true;
}
if (!sync_info)
if (n->hold_timer)
json_object_string_add(
json, "peerActiveHold",
- thread_timer_to_hhmmss(thread_buf,
- sizeof(thread_buf),
- n->hold_timer));
+ event_timer_to_hhmmss(thread_buf,
+ sizeof(thread_buf),
+ n->hold_timer));
}
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
if (n->mac->es) {
/* Duplicate ip detection */
uint32_t dad_count;
- struct thread *dad_ip_auto_recovery_timer;
+ struct event *dad_ip_auto_recovery_timer;
struct timeval detect_start_time;
time_t uptime;
/* used for ageing out the PEER_ACTIVE flag */
- struct thread *hold_timer;
+ struct event *hold_timer;
};
/*
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
zlog_debug("sync-neigh vni %u ip %pIA mac %pEA 0x%x hold stop",
n->zevpn->vni, &n->ip, &n->emac, n->flags);
- THREAD_OFF(n->hold_timer);
+ EVENT_OFF(n->hold_timer);
}
void zebra_evpn_sync_neigh_static_chg(struct zebra_neigh *n, bool old_n_static,
#include "log.h"
#include "libfrr.h"
#include "stream.h"
-#include "thread.h"
+#include "frrevent.h"
#include "network.h"
#include "command.h"
#include "lib/version.h"
*/
enum zfpm_msg_format message_format;
- struct thread_master *master;
+ struct event_loop *master;
enum zfpm_state state;
/*
* Threads for I/O.
*/
- struct thread *t_connect;
- struct thread *t_write;
- struct thread *t_read;
+ struct event *t_connect;
+ struct event *t_write;
+ struct event *t_read;
/*
* Thread to clean up after the TCP connection to the FPM goes down
* and the state that belongs to it.
*/
- struct thread *t_conn_down;
+ struct event *t_conn_down;
struct {
struct zfpm_rnodes_iter iter;
* Thread to take actions once the TCP conn to the FPM comes up, and
* the state that belongs to it.
*/
- struct thread *t_conn_up;
+ struct event *t_conn_up;
struct {
struct zfpm_rnodes_iter iter;
/*
* Stats interval timer.
*/
- struct thread *t_stats;
+ struct event *t_stats;
/*
* If non-zero, the last time when statistics were cleared.
static int zfpm_trigger_update(struct route_node *rn, const char *reason);
-static void zfpm_read_cb(struct thread *thread);
-static void zfpm_write_cb(struct thread *thread);
+static void zfpm_read_cb(struct event *thread);
+static void zfpm_write_cb(struct event *thread);
static void zfpm_set_state(enum zfpm_state state, const char *reason);
static void zfpm_start_connect_timer(const char *reason);
/*
* zfpm_thread_should_yield
*/
-static inline int zfpm_thread_should_yield(struct thread *t)
+static inline int zfpm_thread_should_yield(struct event *t)
{
- return thread_should_yield(t);
+ return event_should_yield(t);
}
/*
assert(!zfpm_g->t_read);
assert(zfpm_g->sock >= 0);
- thread_add_read(zfpm_g->master, zfpm_read_cb, 0, zfpm_g->sock,
- &zfpm_g->t_read);
+ event_add_read(zfpm_g->master, zfpm_read_cb, 0, zfpm_g->sock,
+ &zfpm_g->t_read);
}
/*
assert(!zfpm_g->t_write);
assert(zfpm_g->sock >= 0);
- thread_add_write(zfpm_g->master, zfpm_write_cb, 0, zfpm_g->sock,
- &zfpm_g->t_write);
+ event_add_write(zfpm_g->master, zfpm_write_cb, 0, zfpm_g->sock,
+ &zfpm_g->t_write);
}
/*
*/
static inline void zfpm_read_off(void)
{
- THREAD_OFF(zfpm_g->t_read);
+ EVENT_OFF(zfpm_g->t_read);
}
/*
*/
static inline void zfpm_write_off(void)
{
- THREAD_OFF(zfpm_g->t_write);
+ EVENT_OFF(zfpm_g->t_write);
}
static inline void zfpm_connect_off(void)
{
- THREAD_OFF(zfpm_g->t_connect);
+ EVENT_OFF(zfpm_g->t_connect);
}
/*
* Callback for actions to be taken when the connection to the FPM
* comes up.
*/
-static void zfpm_conn_up_thread_cb(struct thread *thread)
+static void zfpm_conn_up_thread_cb(struct event *thread)
{
struct route_node *rnode;
struct zfpm_rnodes_iter *iter;
zfpm_g->stats.t_conn_up_yields++;
zfpm_rnodes_iter_pause(iter);
- thread_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb,
- NULL, 0, &zfpm_g->t_conn_up);
+ event_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb,
+ NULL, 0, &zfpm_g->t_conn_up);
return;
}
/*
* Start thread to push existing routes to the FPM.
*/
- THREAD_OFF(zfpm_g->t_conn_up);
+ EVENT_OFF(zfpm_g->t_conn_up);
zfpm_rnodes_iter_init(&zfpm_g->t_conn_up_state.iter);
zfpm_g->fpm_mac_dump_done = false;
zfpm_debug("Starting conn_up thread");
- thread_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb, NULL, 0,
- &zfpm_g->t_conn_up);
+ event_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb, NULL, 0,
+ &zfpm_g->t_conn_up);
zfpm_g->stats.t_conn_up_starts++;
}
* Callback that is invoked to clean up state after the TCP connection
* to the FPM goes down.
*/
-static void zfpm_conn_down_thread_cb(struct thread *thread)
+static void zfpm_conn_down_thread_cb(struct event *thread)
{
struct route_node *rnode;
struct zfpm_rnodes_iter *iter;
zfpm_g->stats.t_conn_down_yields++;
zfpm_rnodes_iter_pause(iter);
zfpm_g->t_conn_down = NULL;
- thread_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb,
- NULL, 0, &zfpm_g->t_conn_down);
+ event_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb,
+ NULL, 0, &zfpm_g->t_conn_down);
return;
}
assert(!zfpm_g->t_conn_down);
zfpm_rnodes_iter_init(&zfpm_g->t_conn_down_state.iter);
zfpm_g->t_conn_down = NULL;
- thread_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb, NULL, 0,
- &zfpm_g->t_conn_down);
+ event_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb, NULL, 0,
+ &zfpm_g->t_conn_down);
zfpm_g->stats.t_conn_down_starts++;
zfpm_set_state(ZFPM_STATE_IDLE, detail);
/*
* zfpm_read_cb
*/
-static void zfpm_read_cb(struct thread *thread)
+static void zfpm_read_cb(struct event *thread)
{
size_t already;
struct stream *ibuf;
/*
* zfpm_write_cb
*/
-static void zfpm_write_cb(struct thread *thread)
+static void zfpm_write_cb(struct event *thread)
{
struct stream *s;
int num_writes;
/*
* zfpm_connect_cb
*/
-static void zfpm_connect_cb(struct thread *t)
+static void zfpm_connect_cb(struct event *t)
{
int sock, ret;
struct sockaddr_in serv;
delay_secs = zfpm_calc_connect_delay();
zfpm_debug("scheduling connect in %ld seconds", delay_secs);
- thread_add_timer(zfpm_g->master, zfpm_connect_cb, 0, delay_secs,
- &zfpm_g->t_connect);
+ event_add_timer(zfpm_g->master, zfpm_connect_cb, 0, delay_secs,
+ &zfpm_g->t_connect);
zfpm_set_state(ZFPM_STATE_ACTIVE, reason);
}
/*
* struct zfpm_statsimer_cb
*/
-static void zfpm_stats_timer_cb(struct thread *t)
+static void zfpm_stats_timer_cb(struct event *t)
{
zfpm_g->t_stats = NULL;
return;
zfpm_debug("Stopping existing stats timer");
- THREAD_OFF(zfpm_g->t_stats);
+ EVENT_OFF(zfpm_g->t_stats);
}
/*
{
assert(!zfpm_g->t_stats);
- thread_add_timer(zfpm_g->master, zfpm_stats_timer_cb, 0,
- ZFPM_STATS_IVL_SECS, &zfpm_g->t_stats);
+ event_add_timer(zfpm_g->master, zfpm_stats_timer_cb, 0,
+ ZFPM_STATS_IVL_SECS, &zfpm_g->t_stats);
}
/*
*
* Returns true on success.
*/
-static int zfpm_init(struct thread_master *master)
+static int zfpm_init(struct event_loop *master)
{
int enable = 1;
uint16_t port = 0;
#include "lib/prefix.h"
#include "lib/command.h"
#include "lib/if.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/stream.h"
#include "lib/memory.h"
#include "lib/table.h"
* Forward declaration.
*/
static struct zserv *zebra_gr_find_stale_client(struct zserv *client);
-static void zebra_gr_route_stale_delete_timer_expiry(struct thread *thread);
+static void zebra_gr_route_stale_delete_timer_expiry(struct event *thread);
static int32_t zebra_gr_delete_stale_routes(struct client_gr_info *info);
static void zebra_gr_process_client_stale_routes(struct zserv *client,
vrf_id_t vrf_id);
/* Cancel the stale timer */
if (info->t_stale_removal != NULL) {
- THREAD_OFF(info->t_stale_removal);
+ EVENT_OFF(info->t_stale_removal);
info->t_stale_removal = NULL;
/* Process the stale routes */
- thread_execute(
- zrouter.master,
- zebra_gr_route_stale_delete_timer_expiry,
- info, 1);
+ event_execute(
+ zrouter.master,
+ zebra_gr_route_stale_delete_timer_expiry,
+ info, 1);
}
}
}
TAILQ_REMOVE(&(client->gr_info_queue), info, gr_info);
- THREAD_OFF(info->t_stale_removal);
+ EVENT_OFF(info->t_stale_removal);
XFREE(MTYPE_ZEBRA_GR, info->current_prefix);
&& (info->t_stale_removal == NULL)) {
struct vrf *vrf = vrf_lookup_by_id(info->vrf_id);
- thread_add_timer(
+ event_add_timer(
zrouter.master,
zebra_gr_route_stale_delete_timer_expiry, info,
info->stale_removal_time,
* Delete all the stale routes that have not been refreshed
* post restart.
*/
-static void zebra_gr_route_stale_delete_timer_expiry(struct thread *thread)
+static void zebra_gr_route_stale_delete_timer_expiry(struct event *thread)
{
- struct client_gr_info *info = THREAD_ARG(thread);
+ struct client_gr_info *info = EVENT_ARG(thread);
int32_t cnt = 0;
struct zserv *client;
struct vrf *vrf = vrf_lookup_by_id(info->vrf_id);
__func__, zebra_route_string(client->proto),
VRF_LOGNAME(vrf), info->vrf_id, cnt);
- thread_add_timer(zrouter.master,
- zebra_gr_route_stale_delete_timer_expiry, info,
- ZEBRA_DEFAULT_STALE_UPDATE_DELAY,
- &info->t_stale_removal);
+ event_add_timer(zrouter.master,
+ zebra_gr_route_stale_delete_timer_expiry, info,
+ ZEBRA_DEFAULT_STALE_UPDATE_DELAY,
+ &info->t_stale_removal);
} else {
/* No routes to delete for the VRF */
LOG_GR("%s: Client %s vrf %s(%u) all stale routes processed",
LOG_GR("%s: Client %s canceled stale delete timer vrf %s(%d)",
__func__, zebra_route_string(client->proto),
VRF_LOGNAME(vrf), info->vrf_id);
- THREAD_OFF(info->t_stale_removal);
- thread_execute(zrouter.master,
- zebra_gr_route_stale_delete_timer_expiry, info,
- 0);
+ EVENT_OFF(info->t_stale_removal);
+ event_execute(zrouter.master,
+ zebra_gr_route_stale_delete_timer_expiry, info,
+ 0);
}
}
static void zebra_l2_bridge_vlan_table_destroy(struct hash *vlan_table)
{
- if (vlan_table) {
- hash_clean(vlan_table, zebra_l2_bridge_vlan_free);
- hash_free(vlan_table);
- }
+ hash_clean_and_free(&vlan_table, zebra_l2_bridge_vlan_free);
}
static struct hash *zebra_l2_bridge_vlan_table_create(void)
static bool test_mlag_in_progress;
static int zebra_mlag_signal_write_thread(void);
-static void zebra_mlag_terminate_pthread(struct thread *event);
-static void zebra_mlag_post_data_from_main_thread(struct thread *thread);
+static void zebra_mlag_terminate_pthread(struct event *event);
+static void zebra_mlag_post_data_from_main_thread(struct event *thread);
static void zebra_mlag_publish_process_state(struct zserv *client,
zebra_message_types_t msg_type);
* additional four bytes are for message type
*/
stream_putl_at(s, 0, msg_type);
- thread_add_event(zrouter.master, zebra_mlag_post_data_from_main_thread,
- s, 0, NULL);
+ event_add_event(zrouter.master, zebra_mlag_post_data_from_main_thread,
+ s, 0, NULL);
}
/**********************End of MLAG Interaction********************************/
* This thread reads the clients data from the Global queue and encodes with
* protobuf and pass on to the MLAG socket.
*/
-static void zebra_mlag_client_msg_handler(struct thread *event)
+static void zebra_mlag_client_msg_handler(struct event *event)
{
struct stream *s;
uint32_t wr_count = 0;
* main thread.
*/
if (msg_type == MLAG_DEREGISTER) {
- thread_add_event(zrouter.master,
- zebra_mlag_terminate_pthread,
- NULL, 0, NULL);
+ event_add_event(zrouter.master,
+ zebra_mlag_terminate_pthread,
+ NULL, 0, NULL);
}
}
* during Zebra Init/after MLAG thread is destroyed.
* so it is safe to use without any locking
*/
- thread_add_event(zrouter.mlag_info.th_master,
- zebra_mlag_client_msg_handler, NULL, 0,
- &zrouter.mlag_info.t_write);
+ event_add_event(zrouter.mlag_info.th_master,
+ zebra_mlag_client_msg_handler, NULL, 0,
+ &zrouter.mlag_info.t_write);
return 0;
}
s = stream_new(ZEBRA_HEADER_SIZE + ZEBRA_MLAG_METADATA_LEN);
stream_putl(s, ZEBRA_MLAG_MSG_BCAST);
zclient_create_header(s, msg_type, VRF_DEFAULT);
- thread_add_event(zrouter.master, zebra_mlag_post_data_from_main_thread,
- s, 0, NULL);
+ event_add_event(zrouter.master, zebra_mlag_post_data_from_main_thread,
+ s, 0, NULL);
}
/**************************End of Multi-entrant Apis**************************/
* main thread, because for that access was needed for clients list.
* so instead of forcing the locks, messages will be posted from main thread.
*/
-static void zebra_mlag_post_data_from_main_thread(struct thread *thread)
+static void zebra_mlag_post_data_from_main_thread(struct event *thread)
{
- struct stream *s = THREAD_ARG(thread);
+ struct stream *s = EVENT_ARG(thread);
struct stream *zebra_s = NULL;
struct listnode *node;
struct zserv *client;
* all clients are un-registered for MLAG Updates, terminate the
* MLAG write thread
*/
-static void zebra_mlag_terminate_pthread(struct thread *event)
+static void zebra_mlag_terminate_pthread(struct event *event)
{
if (IS_ZEBRA_DEBUG_MLAG)
zlog_debug("Zebra MLAG write thread terminate called");
#include "hook.h"
#include "module.h"
-#include "thread.h"
+#include "frrevent.h"
#include "frr_pthread.h"
#include "libfrr.h"
#include "lib/version.h"
*
*/
-static struct thread_master *zmlag_master;
+static struct event_loop *zmlag_master;
static int mlag_socket;
-static void zebra_mlag_connect(struct thread *thread);
-static void zebra_mlag_read(struct thread *thread);
+static void zebra_mlag_connect(struct event *thread);
+static void zebra_mlag_read(struct event *thread);
/*
* Write the data to MLAGD
static void zebra_mlag_sched_read(void)
{
- thread_add_read(zmlag_master, zebra_mlag_read, NULL, mlag_socket,
- &zrouter.mlag_info.t_read);
+ event_add_read(zmlag_master, zebra_mlag_read, NULL, mlag_socket,
+ &zrouter.mlag_info.t_read);
}
-static void zebra_mlag_read(struct thread *thread)
+static void zebra_mlag_read(struct event *thread)
{
static uint32_t mlag_rd_buf_offset;
uint32_t *msglen;
zebra_mlag_sched_read();
}
-static void zebra_mlag_connect(struct thread *thread)
+static void zebra_mlag_connect(struct event *thread)
{
struct sockaddr_un svr = {0};
svr.sun_path);
close(mlag_socket);
zrouter.mlag_info.timer_running = true;
- thread_add_timer(zmlag_master, zebra_mlag_connect, NULL, 10,
- &zrouter.mlag_info.t_read);
+ event_add_timer(zmlag_master, zebra_mlag_connect, NULL, 10,
+ &zrouter.mlag_info.t_read);
return;
}
zlog_debug("%s: Connection with MLAG is established ",
__func__);
- thread_add_read(zmlag_master, zebra_mlag_read, NULL, mlag_socket,
- &zrouter.mlag_info.t_read);
+ event_add_read(zmlag_master, zebra_mlag_read, NULL, mlag_socket,
+ &zrouter.mlag_info.t_read);
/*
* Connection is established with MLAGD, post to clients
*/
*/
static int zebra_mlag_private_monitor_state(void)
{
- thread_add_event(zmlag_master, zebra_mlag_connect, NULL, 0,
- &zrouter.mlag_info.t_read);
+ event_add_event(zmlag_master, zebra_mlag_connect, NULL, 0,
+ &zrouter.mlag_info.t_read);
return 0;
}
/*
* Connect only if any clients are showing interest
*/
- thread_add_event(zmlag_master, zebra_mlag_connect, NULL, 0,
- &zrouter.mlag_info.t_read);
+ event_add_event(zmlag_master, zebra_mlag_connect, NULL, 0,
+ &zrouter.mlag_info.t_read);
}
return 0;
}
#include "log.h"
#include "sockunion.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "workqueue.h"
#include "prefix.h"
#include "routemap.h"
struct zebra_lsp *lsp;
struct zebra_nhlfe *oldbest, *newbest;
char buf[BUFSIZ], buf2[BUFSIZ];
- struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
enum zebra_dplane_result res;
lsp = (struct zebra_lsp *)data;
if (zebra_router_in_shutdown())
return;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
assert(zvrf);
lsp_table = zvrf->lsp_table;
case DPLANE_OP_LSP_INSTALL:
case DPLANE_OP_LSP_UPDATE:
/* Look for zebra LSP object */
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (zvrf == NULL)
break;
dplane_ctx_get_in_label(ctx));
/* Look for zebra LSP object */
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (zvrf == NULL)
return;
*/
static int zebra_mpls_cleanup_fecs_for_client(struct zserv *client)
{
- struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
struct route_node *rn;
struct zebra_fec *fec;
struct listnode *node;
void zebra_mpls_close_tables(struct zebra_vrf *zvrf)
{
hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
- hash_clean(zvrf->lsp_table, lsp_table_free);
- hash_free(zvrf->lsp_table);
- hash_clean(zvrf->slsp_table, lsp_table_free);
- hash_free(zvrf->slsp_table);
+ hash_clean_and_free(&zvrf->lsp_table, lsp_table_free);
+ hash_clean_and_free(&zvrf->slsp_table, lsp_table_free);
route_table_finish(zvrf->fec_table[AFI_IP]);
route_table_finish(zvrf->fec_table[AFI_IP6]);
}
return CMD_WARNING_CONFIG_FAILED;
}
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf) {
vty_out(vty, "%% Default VRF does not exist\n");
return CMD_WARNING_CONFIG_FAILED;
uint32_t label;
int ret;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf) {
vty_out(vty, "%% Default VRF does not exist\n");
return CMD_WARNING_CONFIG_FAILED;
int write = 0;
struct zebra_vrf *zvrf;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return 0;
struct prefix p;
int ret;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return 0;
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
zebra_mpls_print_lsp_table(vty, zvrf, uj);
return CMD_SUCCESS;
}
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
label = atoi(argv[3]->arg);
zebra_mpls_print_lsp(vty, zvrf, label, uj);
return CMD_SUCCESS;
#include <sys/inotify.h>
#include <sys/stat.h>
-#include "thread.h"
+#include "frrevent.h"
#include "ns.h"
#include "command.h"
#include "memory.h"
#define ZEBRA_NS_POLLING_MAX_RETRIES 200
DEFINE_MTYPE_STATIC(ZEBRA, NETNS_MISC, "ZebraNetNSInfo");
-static struct thread *zebra_netns_notify_current;
+static struct event *zebra_netns_notify_current;
struct zebra_netns_info {
const char *netnspath;
unsigned int retries;
};
-static void zebra_ns_ready_read(struct thread *t);
+static void zebra_ns_ready_read(struct event *t);
static void zebra_ns_notify_create_context_from_entry_name(const char *name);
static int zebra_ns_continue_read(struct zebra_netns_info *zns_info,
int stop_retry);
-static void zebra_ns_notify_read(struct thread *t);
+static void zebra_ns_notify_read(struct event *t);
static struct vrf *vrf_handler_create(struct vty *vty, const char *vrfname)
{
XFREE(MTYPE_NETNS_MISC, zns_info);
return 0;
}
- thread_add_timer_msec(zrouter.master, zebra_ns_ready_read,
- (void *)zns_info, ZEBRA_NS_POLLING_INTERVAL_MSEC,
- NULL);
+ event_add_timer_msec(zrouter.master, zebra_ns_ready_read,
+ (void *)zns_info, ZEBRA_NS_POLLING_INTERVAL_MSEC,
+ NULL);
return 0;
}
return false;
}
-static void zebra_ns_ready_read(struct thread *t)
+static void zebra_ns_ready_read(struct event *t)
{
- struct zebra_netns_info *zns_info = THREAD_ARG(t);
+ struct zebra_netns_info *zns_info = EVENT_ARG(t);
const char *netnspath;
int err, stop_retry = 0;
zebra_ns_continue_read(zns_info, 1);
}
-static void zebra_ns_notify_read(struct thread *t)
+static void zebra_ns_notify_read(struct event *t)
{
- int fd_monitor = THREAD_FD(t);
+ int fd_monitor = EVENT_FD(t);
struct inotify_event *event;
char buf[BUFSIZ];
ssize_t len;
char event_name[NAME_MAX + 1];
- thread_add_read(zrouter.master, zebra_ns_notify_read, NULL, fd_monitor,
- &zebra_netns_notify_current);
+ event_add_read(zrouter.master, zebra_ns_notify_read, NULL, fd_monitor,
+ &zebra_netns_notify_current);
len = read(fd_monitor, buf, sizeof(buf));
if (len < 0) {
flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ,
sizeof(struct zebra_netns_info));
netnsinfo->retries = ZEBRA_NS_POLLING_MAX_RETRIES;
netnsinfo->netnspath = netnspath;
- thread_add_timer_msec(zrouter.master, zebra_ns_ready_read,
- (void *)netnsinfo, 0, NULL);
+ event_add_timer_msec(zrouter.master, zebra_ns_ready_read,
+ (void *)netnsinfo, 0, NULL);
}
}
"NS notify watch: failed to add watch (%s)",
safe_strerror(errno));
}
- thread_add_read(zrouter.master, zebra_ns_notify_read, NULL, fd_monitor,
- &zebra_netns_notify_current);
+ event_add_read(zrouter.master, zebra_ns_notify_read, NULL, fd_monitor,
+ &zebra_netns_notify_current);
}
void zebra_ns_notify_close(void)
fd = zebra_netns_notify_current->u.fd;
if (zebra_netns_notify_current->master != NULL)
- THREAD_OFF(zebra_netns_notify_current);
+ EVENT_OFF(zebra_netns_notify_current);
/* auto-removal of notify items */
if (fd > 0)
nhe->nhg.nexthop);
}
- THREAD_OFF(nhe->timer);
+ EVENT_OFF(nhe->timer);
zebra_nhg_free_members(nhe);
nhe->nhg.nexthop);
}
- THREAD_OFF(nhe->timer);
+ EVENT_OFF(nhe->timer);
nexthops_free(nhe->nhg.nexthop);
}
}
-static void zebra_nhg_timer(struct thread *thread)
+static void zebra_nhg_timer(struct event *thread)
{
- struct nhg_hash_entry *nhe = THREAD_ARG(thread);
+ struct nhg_hash_entry *nhe = EVENT_ARG(thread);
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug("Nexthop Timer for nhe: %pNG", nhe);
!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_KEEP_AROUND)) {
nhe->refcnt = 1;
SET_FLAG(nhe->flags, NEXTHOP_GROUP_KEEP_AROUND);
- thread_add_timer(zrouter.master, zebra_nhg_timer, nhe,
- zrouter.nhg_keep, &nhe->timer);
+ event_add_timer(zrouter.master, zebra_nhg_timer, nhe,
+ zrouter.nhg_keep, &nhe->timer);
return;
}
nhe->refcnt++;
- if (thread_is_scheduled(nhe->timer)) {
- THREAD_OFF(nhe->timer);
+ if (event_is_scheduled(nhe->timer)) {
+ EVENT_OFF(nhe->timer);
nhe->refcnt--;
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_KEEP_AROUND);
}
/* Dont call the dec API, we dont want to uninstall the ID */
old->refcnt = 0;
- THREAD_OFF(old->timer);
+ EVENT_OFF(old->timer);
zebra_nhg_free(old);
old = NULL;
}
*/
struct nhg_connected_tree_head nhg_depends, nhg_dependents;
- struct thread *timer;
+ struct event *timer;
/*
* Is this nexthop group valid, ie all nexthops are fully resolved.
*/
struct nlsock netlink_dplane_out;
struct nlsock netlink_dplane_in;
- struct thread *t_netlink;
+ struct event *t_netlink;
#endif
struct route_table *if_table;
struct frr_pthread *pthread;
/* Event-delivery context 'master' for the module */
- struct thread_master *master;
+ struct event_loop *master;
/* Event/'thread' pointer for queued zapi messages */
- struct thread *t_msgs;
+ struct event *t_msgs;
/* Input fifo queue to the module, and lock to protect it. */
pthread_mutex_t mutex;
/* Prototypes */
/* Main event loop, processing incoming message queue */
-static void process_messages(struct thread *event);
+static void process_messages(struct event *event);
static int handle_opq_registration(const struct zmsghdr *hdr,
struct stream *msg);
static int handle_opq_unregistration(const struct zmsghdr *hdr,
atomic_store_explicit(&zo_info.run, 1, memory_order_relaxed);
/* Enqueue an initial event for the pthread */
- thread_add_event(zo_info.master, process_messages, NULL, 0,
- &zo_info.t_msgs);
+ event_add_event(zo_info.master, process_messages, NULL, 0,
+ &zo_info.t_msgs);
/* And start the pthread */
frr_pthread_run(zo_info.pthread, NULL);
if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL)
zlog_debug("%s: received %u messages",
__func__, counter);
- thread_add_event(zo_info.master, process_messages, NULL, 0,
- &zo_info.t_msgs);
+ event_add_event(zo_info.master, process_messages, NULL, 0,
+ &zo_info.t_msgs);
}
return counter;
/*
* Pthread event loop, process the incoming message queue.
*/
-static void process_messages(struct thread *event)
+static void process_messages(struct event *event)
{
struct stream_fifo fifo;
struct stream *msg;
if (need_resched) {
atomic_fetch_add_explicit(&zo_info.yields, 1,
memory_order_relaxed);
- thread_add_event(zo_info.master, process_messages, NULL, 0,
- &zo_info.t_msgs);
+ event_add_event(zo_info.master, process_messages, NULL, 0,
+ &zo_info.t_msgs);
}
/* This will also free any leftover messages, in the shutdown case */
struct zebra_ptm_cb ptm_cb;
static int zebra_ptm_socket_init(void);
-void zebra_ptm_sock_read(struct thread *thread);
+void zebra_ptm_sock_read(struct event *thread);
static void zebra_ptm_install_commands(void);
static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt);
void zebra_bfd_peer_replay_req(void);
free(ptm_cb.in_data);
/* Cancel events. */
- THREAD_OFF(ptm_cb.t_read);
- THREAD_OFF(ptm_cb.t_write);
- THREAD_OFF(ptm_cb.t_timer);
+ EVENT_OFF(ptm_cb.t_read);
+ EVENT_OFF(ptm_cb.t_write);
+ EVENT_OFF(ptm_cb.t_timer);
if (ptm_cb.wb)
buffer_free(ptm_cb.wb);
close(ptm_cb.ptm_sock);
}
-static void zebra_ptm_flush_messages(struct thread *thread)
+static void zebra_ptm_flush_messages(struct event *thread)
{
ptm_cb.t_write = NULL;
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
case BUFFER_PENDING:
ptm_cb.t_write = NULL;
- thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
- ptm_cb.ptm_sock, &ptm_cb.t_write);
+ event_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
+ ptm_cb.ptm_sock, &ptm_cb.t_write);
break;
case BUFFER_EMPTY:
break;
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return -1;
case BUFFER_EMPTY:
- THREAD_OFF(ptm_cb.t_write);
+ EVENT_OFF(ptm_cb.t_write);
break;
case BUFFER_PENDING:
- thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
- ptm_cb.ptm_sock, &ptm_cb.t_write);
+ event_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
+ ptm_cb.ptm_sock, &ptm_cb.t_write);
break;
}
return 0;
}
-void zebra_ptm_connect(struct thread *t)
+void zebra_ptm_connect(struct event *t)
{
int init = 0;
if (ptm_cb.ptm_sock != -1) {
if (init) {
ptm_cb.t_read = NULL;
- thread_add_read(zrouter.master, zebra_ptm_sock_read,
- NULL, ptm_cb.ptm_sock, &ptm_cb.t_read);
+ event_add_read(zrouter.master, zebra_ptm_sock_read,
+ NULL, ptm_cb.ptm_sock, &ptm_cb.t_read);
zebra_bfd_peer_replay_req();
}
zebra_ptm_send_status_req();
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX;
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
} else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX) {
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
}
}
}
-void zebra_ptm_sock_read(struct thread *thread)
+void zebra_ptm_sock_read(struct event *thread)
{
int sock;
int rc;
errno = 0;
- sock = THREAD_FD(thread);
+ sock = EVENT_FD(thread);
if (sock == -1)
return;
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time,
- &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
ptm_cb.t_read = NULL;
- thread_add_read(zrouter.master, zebra_ptm_sock_read, NULL,
- ptm_cb.ptm_sock, &ptm_cb.t_read);
+ event_add_read(zrouter.master, zebra_ptm_sock_read, NULL,
+ ptm_cb.ptm_sock, &ptm_cb.t_read);
}
/* BFD peer/dst register/update */
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return;
}
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
- thread_add_timer(zrouter.master, zebra_ptm_connect, NULL,
- ptm_cb.reconnect_time, &ptm_cb.t_timer);
+ event_add_timer(zrouter.master, zebra_ptm_connect, NULL,
+ ptm_cb.reconnect_time, &ptm_cb.t_timer);
return 0;
}
struct buffer *wb; /* Buffer of data waiting to be written to ptm. */
- struct thread *t_read; /* Thread for read */
- struct thread *t_write; /* Thread for write */
- struct thread *t_timer; /* Thread for timer */
+ struct event *t_read; /* Thread for read */
+ struct event *t_write; /* Thread for write */
+ struct event *t_timer; /* Thread for timer */
char *out_data;
char *in_data;
void zebra_ptm_init(void);
void zebra_ptm_finish(void);
-void zebra_ptm_connect(struct thread *t);
+void zebra_ptm_connect(struct event *t);
void zebra_ptm_write(struct vty *vty);
int zebra_ptm_get_enable_state(void);
#include "log.h"
#include "memory.h"
-#include "thread.h"
+#include "frrevent.h"
#include "command.h"
#include "vrf.h"
#include "lib/json.h"
static int zebra_pw_enabled(struct zebra_pw *);
static void zebra_pw_install(struct zebra_pw *);
static void zebra_pw_uninstall(struct zebra_pw *);
-static void zebra_pw_install_retry(struct thread *thread);
+static void zebra_pw_install_retry(struct event *thread);
static int zebra_pw_check_reachability(const struct zebra_pw *);
static void zebra_pw_update_status(struct zebra_pw *, int);
dplane_pw_uninstall(pw);
}
- THREAD_OFF(pw->install_retry_timer);
+ EVENT_OFF(pw->install_retry_timer);
/* unlink and release memory */
RB_REMOVE(zebra_pw_head, &zvrf->pseudowires, pw);
pw->vrf_id, pw->ifname, PW_INSTALL_RETRY_INTERVAL);
/* schedule to retry later */
- THREAD_OFF(pw->install_retry_timer);
- thread_add_timer(zrouter.master, zebra_pw_install_retry, pw,
- PW_INSTALL_RETRY_INTERVAL, &pw->install_retry_timer);
+ EVENT_OFF(pw->install_retry_timer);
+ event_add_timer(zrouter.master, zebra_pw_install_retry, pw,
+ PW_INSTALL_RETRY_INTERVAL, &pw->install_retry_timer);
zebra_pw_update_status(pw, pwstatus);
}
-static void zebra_pw_install_retry(struct thread *thread)
+static void zebra_pw_install_retry(struct event *thread)
{
- struct zebra_pw *pw = THREAD_ARG(thread);
+ struct zebra_pw *pw = EVENT_ARG(thread);
zebra_pw_install(pw);
}
const char *ifname;
int idx = 0;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return CMD_WARNING;
const char *ifname;
int idx = 0;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return CMD_WARNING;
struct zebra_vrf *zvrf;
struct zebra_pw *pw;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return 0;
struct nexthop *nexthop;
struct nexthop_group *nhg;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return;
struct zebra_vrf *zvrf;
struct zebra_pw *pw;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return;
struct zebra_vrf *zvrf;
struct zebra_pw *pw;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return 0;
uint8_t protocol;
struct zserv *client;
struct rnh *rnh;
- struct thread *install_retry_timer;
+ struct event *install_retry_timer;
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(zebra_pw);
#include "sockunion.h"
#include "srcdest_table.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vrf.h"
#include "workqueue.h"
#include "nexthop_group_private.h"
* Event, list, and mutex for delivery of dataplane results
*/
static pthread_mutex_t dplane_mutex;
-static struct thread *t_dplane;
+static struct event *t_dplane;
static struct dplane_ctx_list_head rib_dplane_q;
DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
{
struct nexthop *nexthop;
struct rib_table_info *info = srcdest_rnode_table_info(rn);
- struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
const struct prefix *p, *src_p;
enum zebra_dplane_result ret;
{
struct nexthop *nexthop;
struct rib_table_info *info = srcdest_rnode_table_info(rn);
- struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
if (info->safi != SAFI_UNICAST) {
UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
static void zebra_rib_evaluate_mpls(struct route_node *rn)
{
rib_dest_t *dest = rib_dest_from_rnode(rn);
- struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!dest)
return;
struct rib_table_info *info;
bool rt_delete = false;
- zvrf = vrf_info_lookup(dplane_ctx_get_vrf(ctx));
+ zvrf = zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
/* Locate rn and re(s) from ctx */
if (!w)
return;
- zvrf = vrf_info_lookup(w->vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(w->vrf_id);
if (!zvrf) {
XFREE(MTYPE_WQ_WRAPPER, w);
return;
XFREE(MTYPE_RIB_UPDATE_CTX, *ctx);
}
-static void rib_update_handler(struct thread *thread)
+static void rib_update_handler(struct event *thread)
{
struct rib_update_ctx *ctx;
- ctx = THREAD_ARG(thread);
+ ctx = EVENT_ARG(thread);
rib_update_handle_vrf_all(ctx->event, ZEBRA_ROUTE_ALL);
* Thread list to ensure we don't schedule a ton of events
* if interfaces are flapping for instance.
*/
-static struct thread *t_rib_update_threads[RIB_UPDATE_MAX];
+static struct event *t_rib_update_threads[RIB_UPDATE_MAX];
+
+void rib_update_finish(void)
+{
+ int i;
+
+ for (i = RIB_UPDATE_KERNEL; i < RIB_UPDATE_MAX; i++) {
+ if (event_is_scheduled(t_rib_update_threads[i])) {
+ struct rib_update_ctx *ctx;
+
+ ctx = EVENT_ARG(t_rib_update_threads[i]);
+
+ rib_update_ctx_fini(&ctx);
+ EVENT_OFF(t_rib_update_threads[i]);
+ }
+ }
+}
/* Schedule a RIB update event for all vrfs */
void rib_update(enum rib_update_event event)
{
struct rib_update_ctx *ctx;
- if (thread_is_scheduled(t_rib_update_threads[event]))
+ if (event_is_scheduled(t_rib_update_threads[event]))
+ return;
+
+ if (zebra_router_in_shutdown())
return;
ctx = rib_update_ctx_init(0, event);
- thread_add_event(zrouter.master, rib_update_handler, ctx, 0,
- &t_rib_update_threads[event]);
+ event_add_event(zrouter.master, rib_update_handler, ctx, 0,
+ &t_rib_update_threads[event]);
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__,
}
/* Sweep all RIB tables. */
-void rib_sweep_route(struct thread *t)
+void rib_sweep_route(struct event *t)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
* Handle results from the dataplane system. Dequeue update context
* structs, dispatch to appropriate internal handlers.
*/
-static void rib_process_dplane_results(struct thread *thread)
+static void rib_process_dplane_results(struct event *thread)
{
struct zebra_dplane_ctx *ctx;
struct dplane_ctx_list_head ctxlist;
}
/* Ensure event is signalled to zebra main pthread */
- thread_add_event(zrouter.master, rib_process_dplane_results, NULL, 0,
- &t_dplane);
+ event_add_event(zrouter.master, rib_process_dplane_results, NULL, 0,
+ &t_dplane);
return 0;
}
#include "log.h"
#include "sockunion.h"
#include "linklist.h"
-#include "thread.h"
+#include "frrevent.h"
#include "workqueue.h"
#include "prefix.h"
#include "routemap.h"
*nht_exists = false;
- zvrf = vrf_info_lookup(vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
if (!zvrf)
return;
#include "zebra/zebra_routemap_clippy.c"
static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
-static struct thread *zebra_t_rmap_update = NULL;
+static struct event *zebra_t_rmap_update = NULL;
char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
struct nh_rmap_obj {
zebra_nht_rm_update(rmap_name);
}
-static void zebra_route_map_update_timer(struct thread *thread)
+static void zebra_route_map_update_timer(struct event *thread)
{
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("Event driven route-map update triggered");
if (!value && zebra_t_rmap_update) {
/* Event driven route map updates is being disabled */
/* But there's a pending timer. Fire it off now */
- THREAD_OFF(zebra_t_rmap_update);
+ EVENT_OFF(zebra_t_rmap_update);
zebra_route_map_update_timer(NULL);
}
}
/* Set zebra_rmap_update_timer to 0 so that it wont schedule again */
zebra_rmap_update_timer = 0;
/* Thread off if any scheduled already */
- THREAD_OFF(zebra_t_rmap_update);
+ EVENT_OFF(zebra_t_rmap_update);
route_map_finish();
}
{
/* rmap_update_timer of 0 means don't do route updates */
if (zebra_rmap_update_timer)
- THREAD_OFF(zebra_t_rmap_update);
+ EVENT_OFF(zebra_t_rmap_update);
- thread_add_timer(zrouter.master, zebra_route_map_update_timer,
- NULL, zebra_rmap_update_timer, &zebra_t_rmap_update);
+ event_add_timer(zrouter.master, zebra_route_map_update_timer, NULL,
+ zebra_rmap_update_timer, &zebra_t_rmap_update);
}
static void zebra_route_map_add(const char *rmap_name)
{
struct zebra_router_table *zrt, *tmp;
- THREAD_OFF(zrouter.sweeper);
+ EVENT_OFF(zrouter.sweeper);
RB_FOREACH_SAFE (zrt, zebra_router_table_head, &zrouter.tables, tmp)
zebra_router_free_table(zrt);
/* Free NHE in ID table only since it has unhashable entries as well */
hash_iterate(zrouter.nhgs_id, zebra_nhg_hash_free_zero_id, NULL);
- hash_clean(zrouter.nhgs_id, zebra_nhg_hash_free);
- hash_free(zrouter.nhgs_id);
- hash_clean(zrouter.nhgs, NULL);
- hash_free(zrouter.nhgs);
-
- hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
- hash_free(zrouter.rules_hash);
-
- hash_clean(zrouter.ipset_entry_hash, zebra_pbr_ipset_entry_free),
- hash_clean(zrouter.ipset_hash, zebra_pbr_ipset_free);
- hash_free(zrouter.ipset_hash);
- hash_free(zrouter.ipset_entry_hash);
- hash_clean(zrouter.iptable_hash, zebra_pbr_iptable_free);
- hash_free(zrouter.iptable_hash);
+ hash_clean_and_free(&zrouter.nhgs_id, zebra_nhg_hash_free);
+ hash_clean_and_free(&zrouter.nhgs, NULL);
+
+ hash_clean_and_free(&zrouter.rules_hash, zebra_pbr_rules_free);
+
+ hash_clean_and_free(&zrouter.ipset_entry_hash,
+ zebra_pbr_ipset_entry_free);
+ hash_clean_and_free(&zrouter.ipset_hash, zebra_pbr_ipset_free);
+ hash_clean_and_free(&zrouter.iptable_hash, zebra_pbr_iptable_free);
#ifdef HAVE_SCRIPTING
zebra_script_destroy();
struct frr_pthread *zebra_pth_mlag;
/* MLAG Thread context 'master' */
- struct thread_master *th_master;
+ struct event_loop *th_master;
/*
* Event for Initial MLAG Connection setup & Data Read
* so no issues.
*
*/
- struct thread *t_read;
+ struct event *t_read;
/* Event for MLAG write */
- struct thread *t_write;
+ struct event *t_write;
};
struct zebra_router {
atomic_bool in_shutdown;
/* Thread master */
- struct thread_master *master;
+ struct event_loop *master;
/* Lists of clients who have connected to us */
struct list *client_list;
* Time for when we sweep the rib from old routes
*/
time_t startup_time;
- struct thread *sweeper;
+ struct event *sweeper;
/*
* The hash of nexthop groups associated with this router
return NULL;
}
-static int zebra_snmp_init(struct thread_master *tm)
+static int zebra_snmp_init(struct event_loop *tm)
{
smux_init(tm);
REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
if (re->mtu)
vty_out(vty, ", mtu %u", re->mtu);
if (re->vrf_id != VRF_DEFAULT) {
- zvrf = vrf_info_lookup(re->vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
vty_out(vty, ", vrf %s", zvrf_name(zvrf));
}
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
json_object_string_add(json, "type",
zebra_route_string(nhe->type));
json_object_int_add(json, "refCount", nhe->refcnt);
- if (thread_is_scheduled(nhe->timer))
+ if (event_is_scheduled(nhe->timer))
json_object_string_add(
json, "timeToDeletion",
- thread_timer_to_hhmmss(time_left,
- sizeof(time_left),
- nhe->timer));
+ event_timer_to_hhmmss(time_left,
+ sizeof(time_left),
+ nhe->timer));
json_object_string_add(json, "uptime", up_str);
json_object_string_add(json, "vrf",
vrf_id_to_name(nhe->vrf_id));
vty_out(vty, "ID: %u (%s)\n", nhe->id,
zebra_route_string(nhe->type));
vty_out(vty, " RefCnt: %u", nhe->refcnt);
- if (thread_is_scheduled(nhe->timer))
+ if (event_is_scheduled(nhe->timer))
vty_out(vty, " Time to Deletion: %s",
- thread_timer_to_hhmmss(time_left,
- sizeof(time_left),
- nhe->timer));
+ event_timer_to_hhmmss(time_left,
+ sizeof(time_left),
+ nhe->timer));
vty_out(vty, "\n");
vty_out(vty, " Uptime: %s\n", up_str);
struct zebra_vrf *zvrf = NULL;
int filter = 0;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return CMD_WARNING;
vni_t vni = strtoul(argv[2]->arg, NULL, 10);
struct zebra_vrf *zvrf = NULL;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
if (!zvrf)
return CMD_WARNING;
mac->detect_start_time.tv_sec = 0;
mac->detect_start_time.tv_usec = 0;
mac->dad_dup_detect_time = 0;
- THREAD_OFF(mac->dad_mac_auto_recovery_timer);
+ EVENT_OFF(mac->dad_mac_auto_recovery_timer);
/* warn-only action return */
if (!zvrf->dad_freeze)
nbr->detect_start_time.tv_sec = 0;
nbr->detect_start_time.tv_usec = 0;
nbr->dad_dup_detect_time = 0;
- THREAD_OFF(nbr->dad_ip_auto_recovery_timer);
+ EVENT_OFF(nbr->dad_ip_auto_recovery_timer);
if (!!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
zebra_evpn_neigh_send_add_to_client(zevpn->vni, ip, &nbr->emac,
mac->detect_start_time.tv_sec = 0;
mac->detect_start_time.tv_usec = 0;
mac->dad_dup_detect_time = 0;
- THREAD_OFF(mac->dad_mac_auto_recovery_timer);
+ EVENT_OFF(mac->dad_mac_auto_recovery_timer);
/* Remove all IPs as duplicate associcated with this MAC */
for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
void zebra_vxlan_vni_table_destroy(struct hash *vni_table)
{
- if (vni_table) {
- hash_clean(vni_table, zebra_vxlan_vni_free);
- hash_free(vni_table);
- }
+ hash_clean_and_free(&vni_table, zebra_vxlan_vni_free);
}
int zebra_vxlan_if_vni_table_destroy(struct zebra_if *zif)
#include "lib/sockopt.h" /* for setsockopt_so_recvbuf, setsockopt... */
#include "lib/sockunion.h" /* for sockopt_reuseaddr, sockopt_reuseport */
#include "lib/stream.h" /* for STREAM_SIZE, stream (ptr only), ... */
-#include "lib/thread.h" /* for thread (ptr only), THREAD_ARG, ... */
+#include "frrevent.h" /* for thread (ptr only), EVENT_ARG, ... */
#include "lib/vrf.h" /* for vrf_info_lookup, VRF_DEFAULT */
#include "lib/vty.h" /* for vty_out, vty (ptr only) */
#include "lib/zclient.h" /* for zmsghdr, ZEBRA_HEADER_SIZE, ZEBRA... */
/*
* Zebra server event driver for all client threads.
*
- * This is essentially a wrapper around thread_add_event() that centralizes
+ * This is essentially a wrapper around event_add_event() that centralizes
* those scheduling calls into one place.
*
* All calls to this function schedule an event on the pthread running the
/*
* Zebra server event driver for the main thread.
*
- * This is essentially a wrapper around thread_add_event() that centralizes
+ * This is essentially a wrapper around event_add_event() that centralizes
* those scheduling calls into one place.
*
* All calls to this function schedule an event on Zebra's main pthread.
atomic_store_explicit(&client->pthread->running, false,
memory_order_relaxed);
- THREAD_OFF(client->t_read);
- THREAD_OFF(client->t_write);
+ EVENT_OFF(client->t_read);
+ EVENT_OFF(client->t_write);
zserv_event(client, ZSERV_HANDLE_CLIENT_FAIL);
}
* allows us to expose information about input and output queues to the user in
* terms of number of packets rather than size of data.
*/
-static void zserv_write(struct thread *thread)
+static void zserv_write(struct event *thread)
{
- struct zserv *client = THREAD_ARG(thread);
+ struct zserv *client = EVENT_ARG(thread);
struct stream *msg;
uint32_t wcmd = 0;
struct stream_fifo *cache;
*
* Any failure in any of these actions is handled by terminating the client.
*/
-static void zserv_read(struct thread *thread)
+static void zserv_read(struct event *thread)
{
- struct zserv *client = THREAD_ARG(thread);
+ struct zserv *client = EVENT_ARG(thread);
int sock;
size_t already;
struct stream_fifo *cache;
memory_order_relaxed);
cache = stream_fifo_new();
p2p = p2p_orig;
- sock = THREAD_FD(thread);
+ sock = EVENT_FD(thread);
while (p2p) {
ssize_t nb;
{
switch (event) {
case ZSERV_CLIENT_READ:
- thread_add_read(client->pthread->master, zserv_read, client,
- client->sock, &client->t_read);
+ event_add_read(client->pthread->master, zserv_read, client,
+ client->sock, &client->t_read);
break;
case ZSERV_CLIENT_WRITE:
- thread_add_write(client->pthread->master, zserv_write, client,
- client->sock, &client->t_write);
+ event_add_write(client->pthread->master, zserv_write, client,
+ client->sock, &client->t_write);
break;
}
}
* rely on the read thread to handle queuing this task enough times to process
* everything on the input queue.
*/
-static void zserv_process_messages(struct thread *thread)
+static void zserv_process_messages(struct event *thread)
{
- struct zserv *client = THREAD_ARG(thread);
+ struct zserv *client = EVENT_ARG(thread);
struct stream *msg;
struct stream_fifo *cache = stream_fifo_new();
uint32_t p2p = zrouter.packets_to_process;
* - Free associated resources
* - Free client structure
*
- * This does *not* take any action on the struct thread * fields. These are
+ * This does *not* take any action on the struct event * fields. These are
* managed by the owning pthread and any tasks associated with them must have
* been stopped prior to invoking this function.
*/
zlog_debug("Closing client '%s'",
zebra_route_string(client->proto));
- thread_cancel_event(zrouter.master, client);
- THREAD_OFF(client->t_cleanup);
- THREAD_OFF(client->t_process);
+ event_cancel_event(zrouter.master, client);
+ EVENT_OFF(client->t_cleanup);
+ EVENT_OFF(client->t_process);
/* destroy pthread */
frr_pthread_destroy(client->pthread);
* already have been closed and the thread will most likely have died, but its
* resources still need to be cleaned up.
*/
-static void zserv_handle_client_fail(struct thread *thread)
+static void zserv_handle_client_fail(struct event *thread)
{
- struct zserv *client = THREAD_ARG(thread);
+ struct zserv *client = EVENT_ARG(thread);
zserv_close_client(client);
}
* main pthread.
*/
if (client->is_closed)
- thread_add_event(zrouter.master,
- zserv_handle_client_fail,
- client, 0, &client->t_cleanup);
+ event_add_event(zrouter.master,
+ zserv_handle_client_fail,
+ client, 0, &client->t_cleanup);
}
}
/*
* Accept socket connection.
*/
-static void zserv_accept(struct thread *thread)
+static void zserv_accept(struct event *thread)
{
int accept_sock;
int client_sock;
struct sockaddr_in client;
socklen_t len;
- accept_sock = THREAD_FD(thread);
+ accept_sock = EVENT_FD(thread);
/* Reregister myself. */
zserv_event(NULL, ZSERV_ACCEPT);
{
switch (event) {
case ZSERV_ACCEPT:
- thread_add_read(zrouter.master, zserv_accept, NULL, zsock,
- NULL);
+ event_add_read(zrouter.master, zserv_accept, NULL, zsock, NULL);
break;
case ZSERV_PROCESS_MESSAGES:
- thread_add_event(zrouter.master, zserv_process_messages, client,
- 0, &client->t_process);
+ event_add_event(zrouter.master, zserv_process_messages, client,
+ 0, &client->t_process);
break;
case ZSERV_HANDLE_CLIENT_FAIL:
- thread_add_event(zrouter.master, zserv_handle_client_fail,
- client, 0, &client->t_cleanup);
+ event_add_event(zrouter.master, zserv_handle_client_fail,
+ client, 0, &client->t_cleanup);
}
}
if (info->t_stale_removal) {
vty_out(vty,
"Stale delete timer: %ld sec\n",
- thread_timer_remain_second(
+ event_timer_remain_second(
info->t_stale_removal));
}
}
#include "lib/vrf.h" /* for vrf_bitmap_t */
#include "lib/zclient.h" /* for redist_proto */
#include "lib/stream.h" /* for stream, stream_fifo */
-#include "lib/thread.h" /* for thread, thread_master */
+#include "frrevent.h" /* for thread, thread_master */
#include "lib/linklist.h" /* for list */
#include "lib/workqueue.h" /* for work_queue */
#include "lib/hook.h" /* for DECLARE_HOOK, DECLARE_KOOH */
/* Book keeping */
struct prefix *current_prefix;
void *stale_client_ptr;
- struct thread *t_stale_removal;
+ struct event *t_stale_removal;
TAILQ_ENTRY(client_gr_info) gr_info;
};
struct buffer *wb;
/* Threads for read/write. */
- struct thread *t_read;
- struct thread *t_write;
+ struct event *t_read;
+ struct event *t_write;
/* Event for message processing, for the main pthread */
- struct thread *t_process;
+ struct event *t_process;
/* Event for the main pthread */
- struct thread *t_cleanup;
+ struct event *t_cleanup;
/* This client's redistribute flag. */
struct redist_proto mi_redist[AFI_MAX][ZEBRA_ROUTE_MAX];
struct zmsghdr *hdr);
/* TODO */
-__attribute__((__noreturn__)) void zebra_finalize(struct thread *event);
+__attribute__((__noreturn__)) void zebra_finalize(struct event *event);
/*
* Graceful restart functions.