Move vrrp_net_listen() to vrrp.c:vrrp_listen() and listen control fifo fd. Add CTRL_FIFO event. Close #1715.
This commit is contained in:
parent
2d1ea0dc75
commit
2887d74a01
88
vrrp.c
88
vrrp.c
|
@ -20,10 +20,15 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
/* pselect() */
|
||||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "vrrp.h"
|
||||
#include "vrrp_timer.h"
|
||||
#include "vrrp_net.h"
|
||||
#include "vrrp_state.h"
|
||||
#include "vrrp_ctrl.h"
|
||||
|
||||
#include "uvrrpd.h"
|
||||
#include "bits.h"
|
||||
|
@ -110,6 +115,89 @@ int vrrp_process(struct vrrp *vrrp, struct vrrp_net *vnet)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrrp_listen() - Wait for a event (VRRP pkt, msg on fifo ...)
|
||||
*
|
||||
* @return vrrp_event_t
|
||||
* TIMER if current timer is expired
|
||||
* another event else
|
||||
*/
|
||||
vrrp_event_t vrrp_listen(struct vrrp *vrrp, struct vrrp_net *vnet)
|
||||
{
|
||||
struct vrrp_timer *vt;
|
||||
int max_fd;
|
||||
|
||||
/* Check which timer is running
|
||||
* Advertisement timer or Masterdown timer ?
|
||||
*/
|
||||
if (vrrp_timer_is_running(&vrrp->adv_timer)) {
|
||||
log_debug("vrid %d :: adv_timer is running", vrrp->vrid);
|
||||
vt = &vrrp->adv_timer;
|
||||
}
|
||||
else if (vrrp_timer_is_running(&vrrp->masterdown_timer)) {
|
||||
log_debug("vrid %d :: masterdown_timer is running", vrrp->vrid);
|
||||
vt = &vrrp->masterdown_timer;
|
||||
}
|
||||
else { /* No timer ? ... exit */
|
||||
log_error("vrid %d :: no timer running !", vrrp->vrid);
|
||||
/* TODO die() */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* update timer before pselect() */
|
||||
if (vrrp_timer_update(vt)) {
|
||||
log_debug("vrid %d :: timer expired before pselect",
|
||||
vrrp->vrid);
|
||||
/* timer expired or invalid */
|
||||
return TIMER;
|
||||
}
|
||||
|
||||
/* pselect */
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(vnet->socket, &readfds);
|
||||
FD_SET(vrrp->ctrl.fd, &readfds);
|
||||
max_fd = max(vnet->socket, vrrp->ctrl.fd);
|
||||
|
||||
sigset_t emptyset;
|
||||
sigemptyset(&emptyset);
|
||||
|
||||
/* Wait for packet or timer expiration */
|
||||
if (pselect
|
||||
(max_fd + 1, &readfds, NULL, NULL,
|
||||
(const struct timespec *) &vt->delta, &emptyset) >= 0) {
|
||||
|
||||
|
||||
/* Timer is expired */
|
||||
if (vrrp_timer_is_expired(vt)) {
|
||||
log_debug("vrid %d :: timer expired", vrrp->vrid);
|
||||
return TIMER;
|
||||
}
|
||||
|
||||
/* Else we have received a pkt */
|
||||
log_debug("vrid %d :: VRRP pkt received", vrrp->vrid);
|
||||
|
||||
if (FD_ISSET(vnet->socket, &readfds))
|
||||
/* check if received is valid or not */
|
||||
return vrrp_net_recv(vnet, vrrp);
|
||||
|
||||
if (FD_ISSET(vrrp->ctrl.fd, &readfds)) {
|
||||
return vrrp_ctrl_read(vrrp, vnet);
|
||||
}
|
||||
}
|
||||
else { /* Signal or pselect error */
|
||||
if (errno == EINTR) {
|
||||
log_debug("vrid %d :: signal caught", vrrp->vrid);
|
||||
|
||||
return SIGNAL;
|
||||
}
|
||||
|
||||
log_error("vrid %d :: pselect - %m", vrrp->vrid);
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vrrp_cleanup() - clean before exiting
|
||||
|
|
15
vrrp.h
15
vrrp.h
|
@ -29,6 +29,7 @@
|
|||
#include "vrrp_net.h"
|
||||
#include "vrrp_timer.h"
|
||||
#include "vrrp_state.h"
|
||||
#include "vrrp_ctrl.h"
|
||||
|
||||
/* MAX values */
|
||||
#define VRID_MAX 255
|
||||
|
@ -114,9 +115,23 @@ struct vrrp {
|
|||
struct vrrp_timer masterdown_timer;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum vrrp_ret - Return code used in vrrp_net_listen
|
||||
*/
|
||||
enum _vrrp_event_type {
|
||||
VRID_MISMATCH = -2, /* vrid mismatch */
|
||||
INVALID = -1, /* invalid pkt */
|
||||
PKT, /* valid packet */
|
||||
SIGNAL, /* signal catch */
|
||||
CTRL_FIFO, /* ctrl cmd event */
|
||||
TIMER /* timer expired */
|
||||
};
|
||||
|
||||
typedef enum _vrrp_event_type vrrp_event_t;
|
||||
/* funcs */
|
||||
void vrrp_init(struct vrrp *vrrp);
|
||||
void vrrp_cleanup(struct vrrp *vrrp);
|
||||
int vrrp_process(struct vrrp *vrrp, struct vrrp_net *vnet);
|
||||
vrrp_event_t vrrp_listen(struct vrrp *vrrp, struct vrrp_net *vnet);
|
||||
|
||||
#endif /* _VRRP_H_ */
|
||||
|
|
14
vrrp_adv.h
14
vrrp_adv.h
|
@ -48,6 +48,20 @@ static inline int vrrp_adv_get_priority(const struct vrrp_net *vnet)
|
|||
return vnet->__pkt.adv.priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrrp_adv_set_priority() - set priority in emitted adv pkt
|
||||
*/
|
||||
static inline void vrrp_adv_set_priority(struct vrrp_net *vnet, uint8_t prio)
|
||||
{
|
||||
struct vrrphdr *pkt = vnet->__adv[2].iov_base;
|
||||
pkt->priority = prio;
|
||||
|
||||
/* recompute chksum */
|
||||
pkt->chksum = vnet->adv_checksum(vnet, pkt, NULL, NULL);
|
||||
|
||||
log_notice("vrid %d :: new prio %d applied", vnet->vrid, pkt->priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* vrrp_adv_addr_to_str() - return source ip from received adv pkt
|
||||
* in string format
|
||||
|
|
81
vrrp_ctrl.c
81
vrrp_ctrl.c
|
@ -28,19 +28,19 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "vrrp_ctrl.h"
|
||||
#include "vrrp.h"
|
||||
#include "common.h"
|
||||
#include "vrrp_ctrl.h"
|
||||
#include "vrrp_adv.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "uvrrpd.h"
|
||||
#include "bits.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
extern unsigned long reg;
|
||||
|
||||
|
||||
static inline vrrp_event_t vrrp_ctrl_cmd(struct vrrp *vrrp);
|
||||
static inline vrrp_event_t vrrp_ctrl_cmd(struct vrrp *vrrp,
|
||||
struct vrrp_net *vnet);
|
||||
|
||||
/**
|
||||
* flush_fifo() - flush a fifo fd
|
||||
|
@ -93,6 +93,7 @@ static inline int split_cmd(char *str, char **words_ptr, int max_words,
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
return nword;
|
||||
}
|
||||
|
||||
|
@ -101,7 +102,7 @@ static inline int split_cmd(char *str, char **words_ptr, int max_words,
|
|||
*/
|
||||
int vrrp_ctrl_init(struct vrrp_ctrl *ctrl)
|
||||
{
|
||||
ctrl->cmd = malloc(sizeof(char *) * CTRL_CMD_TOKEN);
|
||||
ctrl->cmd = malloc(sizeof(char *) * CTRL_CMD_NTOKEN);
|
||||
|
||||
if (ctrl->cmd == NULL) {
|
||||
log_error("init :: malloc - %m");
|
||||
|
@ -114,51 +115,105 @@ int vrrp_ctrl_init(struct vrrp_ctrl *ctrl)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* vrrp_ctrl_cmd_flush() - Flush cmd
|
||||
*/
|
||||
static inline void vrrp_ctrl_cmd_flush(struct vrrp_ctrl *ctrl)
|
||||
{
|
||||
if (ctrl == NULL)
|
||||
return;
|
||||
|
||||
/* clean buff */
|
||||
for (int i = 0; i < CTRL_CMD_NTOKEN; ctrl->cmd[i++] = NULL);
|
||||
bzero(ctrl->msg, CTRL_MAXCHAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* vrrp_ctrl_cmd() - Interprete control fifo cmd
|
||||
*/
|
||||
static inline vrrp_event_t vrrp_ctrl_cmd(struct vrrp *vrrp)
|
||||
static inline vrrp_event_t vrrp_ctrl_cmd(struct vrrp *vrrp,
|
||||
struct vrrp_net *vnet)
|
||||
{
|
||||
int nword;
|
||||
|
||||
nword =
|
||||
split_cmd(vrrp->ctrl.msg, vrrp->ctrl.cmd, CTRL_CMD_TOKEN,
|
||||
split_cmd(vrrp->ctrl.msg, vrrp->ctrl.cmd, CTRL_CMD_NTOKEN,
|
||||
WHITESPACE);
|
||||
|
||||
if (nword == 0)
|
||||
return INVALID;
|
||||
|
||||
|
||||
/*
|
||||
* control cmd stop
|
||||
*/
|
||||
if (matches(vrrp->ctrl.cmd[0], "stop")) {
|
||||
log_notice("vrid %d :: control cmd stop, exiting", vrrp->vrid);
|
||||
set_bit(UVRRPD_RELOAD, ®);
|
||||
clear_bit(KEEP_GOING, ®);
|
||||
vrrp_ctrl_cmd_flush(&vrrp->ctrl);
|
||||
return CTRL_FIFO;
|
||||
}
|
||||
|
||||
/*
|
||||
* control cmd reload
|
||||
*/
|
||||
if (matches(vrrp->ctrl.cmd[0], "reload")) {
|
||||
set_bit(UVRRPD_RELOAD, ®);
|
||||
vrrp_ctrl_cmd_flush(&vrrp->ctrl);
|
||||
return CTRL_FIFO;
|
||||
}
|
||||
|
||||
/*
|
||||
* control cmd state || status
|
||||
*/
|
||||
if (matches(vrrp->ctrl.cmd[0], "state")
|
||||
|| matches(vrrp->ctrl.cmd[0], "status")) {
|
||||
|
||||
set_bit(UVRRPD_DUMP, ®);
|
||||
/* dump state in logs */
|
||||
vrrp_ctrl_cmd_flush(&vrrp->ctrl);
|
||||
}
|
||||
|
||||
/*
|
||||
* control cmd prio
|
||||
*/
|
||||
if (matches(vrrp->ctrl.cmd[0], "prio")) {
|
||||
if (nword != 2) {
|
||||
/* error */
|
||||
log_error
|
||||
("vrid %d :: invalid syntax, control cmd prio <priority>",
|
||||
vrrp->vrid);
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
/* fetch priority */
|
||||
int err;
|
||||
unsigned long opt;
|
||||
err = mystrtoul(&opt, vrrp->ctrl.cmd[1], VRRP_PRIO_MAX);
|
||||
|
||||
vrrp_ctrl_cmd_flush(&vrrp->ctrl);
|
||||
|
||||
if (err == -ERANGE) {
|
||||
log_error
|
||||
("vrid %d :: invalid control cmd prio, 0 < priority < 255",
|
||||
vrrp->vrid);
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (err == -EINVAL) {
|
||||
log_error
|
||||
("vrid %d :: invalid control cmd prio, error parsing \"%s\" as a number",
|
||||
vrrp->vrid, vrrp->ctrl.cmd[1]);
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
vrrp->priority = (uint8_t) opt;
|
||||
|
||||
/* change prio */
|
||||
// todo
|
||||
vrrp_adv_set_priority(vnet, vrrp->priority);
|
||||
|
||||
/* reload bit */
|
||||
set_bit(UVRRPD_RELOAD, ®);
|
||||
|
||||
return CTRL_FIFO;
|
||||
}
|
||||
|
||||
|
@ -168,7 +223,7 @@ static inline vrrp_event_t vrrp_ctrl_cmd(struct vrrp *vrrp)
|
|||
/**
|
||||
* vrrp_ctrl_read() - Read control fifo
|
||||
*/
|
||||
vrrp_event_t vrrp_ctrl_read(struct vrrp * vrrp)
|
||||
vrrp_event_t vrrp_ctrl_read(struct vrrp * vrrp, struct vrrp_net * vnet)
|
||||
{
|
||||
int readbytes = 0;
|
||||
|
||||
|
@ -177,7 +232,7 @@ vrrp_event_t vrrp_ctrl_read(struct vrrp * vrrp)
|
|||
if (readbytes > 0) {
|
||||
flush_fifo(vrrp->ctrl.fd);
|
||||
vrrp->ctrl.msg[CTRL_MAXCHAR - 1] = '\0';
|
||||
return vrrp_ctrl_cmd(vrrp);
|
||||
return vrrp_ctrl_cmd(vrrp, vnet);
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
|
|
|
@ -26,10 +26,11 @@
|
|||
|
||||
/* from vrrp.h */
|
||||
struct vrrp;
|
||||
struct vrrp_net;
|
||||
typedef enum _vrrp_event_type vrrp_event_t;
|
||||
|
||||
#define CTRL_MAXCHAR 64
|
||||
#define CTRL_CMD_TOKENS 3
|
||||
#define CTRL_CMD_NTOKEN 3
|
||||
|
||||
/**
|
||||
* vrrp_ctrl - infos about control fifo
|
||||
|
@ -49,7 +50,7 @@ struct vrrp_ctrl {
|
|||
|
||||
int vrrp_ctrl_init(struct vrrp_ctrl *ctrl);
|
||||
void vrrp_ctrl_cleanup(struct vrrp_ctrl *ctrl);
|
||||
vrrp_event_t vrrp_ctrl_read(struct vrrp *vrrp);
|
||||
vrrp_event_t vrrp_ctrl_read(struct vrrp *vrrp, struct vrrp_net *vnet);
|
||||
|
||||
|
||||
#endif /* _VRRP_CTRL_H_ */
|
||||
|
|
79
vrrp_net.c
79
vrrp_net.c
|
@ -32,16 +32,13 @@
|
|||
/* ifreq + ioctl */
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
/* pselect() */
|
||||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h> /* NI_MAXHOST */
|
||||
|
||||
#include "vrrp.h"
|
||||
#include "vrrp_net.h"
|
||||
#include "vrrp_timer.h"
|
||||
#include "vrrp_adv.h"
|
||||
|
||||
#include "common.h"
|
||||
|
@ -249,80 +246,6 @@ int vrrp_net_vip_set(struct vrrp_net *vnet, const char *ip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrrp_net_listen() - Wait for a VRRP pkt on vnet->socket
|
||||
*
|
||||
* @return vrrp_event_t
|
||||
* TIMER if current timer is expired
|
||||
* another event else
|
||||
*/
|
||||
vrrp_event_t vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp)
|
||||
{
|
||||
struct vrrp_timer *vt;
|
||||
|
||||
/* Check which timer is running
|
||||
* Advertisement timer or Masterdown timer ?
|
||||
*/
|
||||
if (vrrp_timer_is_running(&vrrp->adv_timer)) {
|
||||
log_debug("vrid %d :: adv_timer is running", vrrp->vrid);
|
||||
vt = &vrrp->adv_timer;
|
||||
}
|
||||
else if (vrrp_timer_is_running(&vrrp->masterdown_timer)) {
|
||||
log_debug("vrid %d :: masterdown_timer is running", vrrp->vrid);
|
||||
vt = &vrrp->masterdown_timer;
|
||||
}
|
||||
else { /* No timer ? ... exit */
|
||||
log_error("vrid %d :: no timer running !", vrrp->vrid);
|
||||
/* TODO die() */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* update timer before pselect() */
|
||||
if (vrrp_timer_update(vt)) {
|
||||
log_debug("vrid %d :: timer expired before pselect",
|
||||
vrrp->vrid);
|
||||
/* timer expired or invalid */
|
||||
return TIMER;
|
||||
}
|
||||
|
||||
/* pselect */
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(vnet->socket, &readfds);
|
||||
|
||||
sigset_t emptyset;
|
||||
sigemptyset(&emptyset);
|
||||
|
||||
/* Wait for packet or timer expiration */
|
||||
if (pselect
|
||||
(vnet->socket + 1, &readfds, NULL, NULL,
|
||||
(const struct timespec *) &vt->delta, &emptyset) >= 0) {
|
||||
|
||||
|
||||
/* Timer is expired */
|
||||
if (vrrp_timer_is_expired(vt)) {
|
||||
log_debug("vrid %d :: timer expired", vrrp->vrid);
|
||||
return TIMER;
|
||||
}
|
||||
|
||||
/* Else we have received a pkt */
|
||||
log_debug("vrid %d :: VRRP pkt received", vrrp->vrid);
|
||||
|
||||
/* check if received is valid or not */
|
||||
return vrrp_net_recv(vnet, vrrp);
|
||||
}
|
||||
else { /* Signal or pselect error */
|
||||
if (errno == EINTR) {
|
||||
log_debug("vrid %d :: signal caught", vrrp->vrid);
|
||||
|
||||
return SIGNAL;
|
||||
}
|
||||
|
||||
log_error("vrid %d :: pselect - %m", vrrp->vrid);
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrrp_net_invalidate_buffer()
|
||||
|
|
14
vrrp_net.h
14
vrrp_net.h
|
@ -39,6 +39,7 @@
|
|||
|
||||
/* from vrrp.h */
|
||||
struct vrrp;
|
||||
typedef enum _vrrp_event_type vrrp_event_t;
|
||||
|
||||
/**
|
||||
* constants
|
||||
|
@ -136,18 +137,6 @@ struct vrrp_net {
|
|||
#define ipx_to_str ipx_helper->ipx_ntop
|
||||
#define str_to_ipx ipx_helper->ipx_pton
|
||||
|
||||
/**
|
||||
* enum vrrp_ret - Return code used in vrrp_net_listen
|
||||
*/
|
||||
enum _vrrp_event_type {
|
||||
VRID_MISMATCH = -2, /* vrid mismatch */
|
||||
INVALID = -1, /* invalid pkt */
|
||||
PKT, /* valid packet */
|
||||
SIGNAL, /* signal catch */
|
||||
TIMER /* timer expired */
|
||||
};
|
||||
|
||||
typedef enum _vrrp_event_type vrrp_event_t;
|
||||
|
||||
/*
|
||||
* funcs
|
||||
|
@ -159,7 +148,6 @@ int vrrp_net_socket_xmit(struct vrrp_net *vnet);
|
|||
int vrrp_net_vif_getaddr(struct vrrp_net *vnet);
|
||||
int vrrp_net_vif_mtu(struct vrrp_net *vnet);
|
||||
int vrrp_net_vip_set(struct vrrp_net *vnet, const char *ip);
|
||||
vrrp_event_t vrrp_net_listen(struct vrrp_net *vnet, struct vrrp *vrrp);
|
||||
vrrp_event_t vrrp_net_recv(struct vrrp_net *vnet, const struct vrrp *vrrp);
|
||||
int vrrp_net_send(const struct vrrp_net *vnet, struct iovec *iov, size_t len);
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ int vrrp_state_init(struct vrrp *vrrp, struct vrrp_net *vnet)
|
|||
*/
|
||||
int vrrp_state_backup(struct vrrp *vrrp, struct vrrp_net *vnet)
|
||||
{
|
||||
int event = vrrp_net_listen(vnet, vrrp);
|
||||
int event = vrrp_listen(vrrp, vnet);
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
|
||||
switch (event) {
|
||||
|
@ -134,7 +134,7 @@ int vrrp_state_backup(struct vrrp *vrrp, struct vrrp_net *vnet)
|
|||
|
||||
case SIGNAL:
|
||||
log_debug("vrid %d :: signal", vrrp->vrid);
|
||||
|
||||
case CTRL_FIFO:
|
||||
/* shutdown/reload event ? */
|
||||
if (test_and_clear_bit(UVRRPD_RELOAD, ®)) {
|
||||
vrrp_timer_clear(&vrrp->masterdown_timer);
|
||||
|
@ -168,7 +168,7 @@ int vrrp_state_backup(struct vrrp *vrrp, struct vrrp_net *vnet)
|
|||
*/
|
||||
int vrrp_state_master(struct vrrp *vrrp, struct vrrp_net *vnet)
|
||||
{
|
||||
int event = vrrp_net_listen(vnet, vrrp);
|
||||
int event = vrrp_listen(vrrp, vnet);
|
||||
|
||||
switch (event) {
|
||||
case TIMER: /* TIMER expired */
|
||||
|
@ -245,6 +245,7 @@ int vrrp_state_master(struct vrrp *vrrp, struct vrrp_net *vnet)
|
|||
|
||||
case SIGNAL:
|
||||
log_debug("vrid %d :: signal", vrrp->vrid);
|
||||
case CTRL_FIFO:
|
||||
|
||||
/* shutdown/reload event ? */
|
||||
if (test_and_clear_bit(UVRRPD_RELOAD, ®)) {
|
||||
|
|
Loading…
Reference in a new issue