diff --git a/Makefile.am b/Makefile.am
index fc56307..92c95ba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,7 @@ noinst_HEADERS = \
uvrrpd.h \
vrrp_adv.h \
vrrp_arp.h \
+ vrrp_ctrl.h \
vrrp_exec.h \
vrrp.h \
vrrp_ipx.h \
@@ -32,6 +33,7 @@ uvrrpd_SOURCES = \
uvrrpd.c \
vrrp_adv.c \
vrrp_arp.c \
+ vrrp_ctrl.c \
vrrp.c \
vrrp_exec.c \
vrrp_ip4.c \
diff --git a/common.h b/common.h
index 1d38b5b..b21c447 100644
--- a/common.h
+++ b/common.h
@@ -75,6 +75,11 @@ typedef enum {
_a > _b ? _a : _b; \
})
+/**
+ * WHITESPACE
+ */
+#define WHITESPACE " \f\r\t\n\v"
+
/**
* cksum - compute IP checksum
*/
diff --git a/vrrp_ctrl.c b/vrrp_ctrl.c
new file mode 100644
index 0000000..be69a5c
--- /dev/null
+++ b/vrrp_ctrl.c
@@ -0,0 +1,193 @@
+/*
+ * vrrp_ctrl.c - control fifo
+ *
+ * Copyright (C) 2016 Arnaud Andre
+ *
+ * This file is part of uvrrpd.
+ *
+ * uvrrpd 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * uvrrpd 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 uvrrpd. If not, see .
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "vrrp_ctrl.h"
+#include "vrrp.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);
+
+/**
+ * flush_fifo() - flush a fifo fd
+ */
+#define BUFLUSH 2048
+
+static inline int flush_fifo(int fd)
+{
+ ssize_t bytes;
+ char buf[BUFLUSH];
+
+ while (1) {
+ bytes = read(fd, buf, sizeof(buf));
+ if (bytes <= 0) {
+ if (errno == EWOULDBLOCK) {
+ return 0;
+ }
+ else {
+ log_error("read - %m");
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * split_cmd() - split a *str in words separated by delim
+ * Fill a *words_ptr[max_words] with ptr to each found word
+ * words_ptr must be pre-allocated
+ * @return nword, number of found word,
+ * -1 if entry str or words_ptr NULL
+ */
+static inline int split_cmd(char *str, char **words_ptr, int max_words,
+ char *delim)
+{
+ if ((str == NULL) || (words_ptr == NULL))
+ return -1;
+
+ int nword;
+ for (nword = 0; nword < max_words; ++nword) {
+ if (str != NULL) {
+ while (isspace(*str))
+ str++; /* trim whitespace */
+ if (str[0] != '\0')
+ words_ptr[nword] = strsep(&str, delim);
+ }
+
+ if (words_ptr[nword] == NULL)
+ break;
+ }
+
+ return nword;
+}
+
+/**
+ * vrrp_ctrl_init()
+ */
+int vrrp_ctrl_init(struct vrrp_ctrl *ctrl)
+{
+ ctrl->cmd = malloc(sizeof(char *) * CTRL_CMD_TOKEN);
+
+ if (ctrl->cmd == NULL) {
+ log_error("init :: malloc - %m");
+ return -1;
+ }
+
+ bzero(ctrl->msg, CTRL_MAXCHAR);
+
+ return 0;
+}
+
+
+/**
+ * vrrp_ctrl_cmd() - Interprete control fifo cmd
+ */
+static inline vrrp_event_t vrrp_ctrl_cmd(struct vrrp *vrrp)
+{
+ int nword;
+
+ nword =
+ split_cmd(vrrp->ctrl.msg, vrrp->ctrl.cmd, CTRL_CMD_TOKEN,
+ WHITESPACE);
+
+ if (nword == 0)
+ return INVALID;
+
+
+ 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, ®);
+ return CTRL_FIFO;
+ }
+
+ if (matches(vrrp->ctrl.cmd[0], "reload")) {
+ set_bit(UVRRPD_RELOAD, ®);
+ return CTRL_FIFO;
+ }
+
+ if (matches(vrrp->ctrl.cmd[0], "state")
+ || matches(vrrp->ctrl.cmd[0], "status")) {
+
+ set_bit(UVRRPD_DUMP, ®);
+ /* dump state in logs */
+ }
+
+ if (matches(vrrp->ctrl.cmd[0], "prio")) {
+ if (nword != 2) {
+ /* error */
+ return INVALID;
+ }
+
+ /* change prio */
+ // todo
+
+ /* reload bit */
+ set_bit(UVRRPD_RELOAD, ®);
+ return CTRL_FIFO;
+ }
+
+ return INVALID;
+}
+
+/**
+ * vrrp_ctrl_read() - Read control fifo
+ */
+vrrp_event_t vrrp_ctrl_read(struct vrrp * vrrp)
+{
+ int readbytes = 0;
+
+ readbytes = read(vrrp->ctrl.fd, vrrp->ctrl.msg, CTRL_MAXCHAR);
+
+ if (readbytes > 0) {
+ flush_fifo(vrrp->ctrl.fd);
+ vrrp->ctrl.msg[CTRL_MAXCHAR - 1] = '\0';
+ return vrrp_ctrl_cmd(vrrp);
+ }
+
+ return INVALID;
+}
+
+
+/**
+ * vrrp_ctrl_cleanup()
+ */
+void vrrp_ctrl_cleanup(struct vrrp_ctrl *ctrl)
+{
+ free(ctrl->cmd);
+}
diff --git a/vrrp_ctrl.h b/vrrp_ctrl.h
new file mode 100644
index 0000000..d02ccf5
--- /dev/null
+++ b/vrrp_ctrl.h
@@ -0,0 +1,55 @@
+/*
+ * vrrp_ctrl.h - control fifo header
+ *
+ * Copyright (C) 2016 Arnaud Andre
+ *
+ * This file is part of uvrrpd.
+ *
+ * uvrrpd 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * uvrrpd 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 uvrrpd. If not, see .
+ */
+
+#ifndef _VRRP_CTRL_H_
+#define _VRRP_CTRL_H_
+
+#include
+
+/* from vrrp.h */
+struct vrrp;
+typedef enum _vrrp_event_type vrrp_event_t;
+
+#define CTRL_MAXCHAR 64
+#define CTRL_CMD_TOKENS 3
+
+/**
+ * vrrp_ctrl - infos about control fifo
+ */
+struct vrrp_ctrl {
+ /* control fifo fd */
+ int fd;
+
+ /* control fifo msg */
+ char msg[CTRL_MAXCHAR];
+
+ /* reformated command */
+ char **cmd;
+};
+
+
+
+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);
+
+
+#endif /* _VRRP_CTRL_H_ */