Commit 84bd1642 by Cédric Le Ninivin Committed by Killian Lufau

New -X option to control babeld via a unix socket

TODO: documentation

To be pushed upstream.

Co-authored-by: Julien Muchembled <jm@nexedi.com>
1 parent ef6a2167
...@@ -11,11 +11,11 @@ LDLIBS = -lrt ...@@ -11,11 +11,11 @@ LDLIBS = -lrt
SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \ SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \
route.c xroute.c message.c resend.c configuration.c local.c \ route.c xroute.c message.c resend.c configuration.c local.c \
disambiguation.c rule.c disambiguation.c rule c ctl.c
OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \ OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \
route.o xroute.o message.o resend.o configuration.o local.o \ route.o xroute.o message.o resend.o configuration.o local.o \
disambiguation.o rule.o disambiguation.o rule.o ctl.o
babeld: $(OBJS) babeld: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS) $(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)
......
...@@ -54,6 +54,7 @@ THE SOFTWARE. ...@@ -54,6 +54,7 @@ THE SOFTWARE.
#include "local.h" #include "local.h"
#include "rule.h" #include "rule.h"
#include "version.h" #include "version.h"
#include "ctl.h"
struct timeval now; struct timeval now;
...@@ -153,6 +154,7 @@ main(int argc, char **argv) ...@@ -153,6 +154,7 @@ main(int argc, char **argv)
void *vrc; void *vrc;
unsigned int seed; unsigned int seed;
struct interface *ifp; struct interface *ifp;
int ctl_sockfd;
gettime(&now); gettime(&now);
...@@ -172,7 +174,7 @@ main(int argc, char **argv) ...@@ -172,7 +174,7 @@ main(int argc, char **argv)
while(1) { while(1) {
opt = getopt(argc, argv, opt = getopt(argc, argv,
"m:p:h:H:i:k:A:srS:d:g:G:lwz:M:t:T:c:C:DL:I:V"); "m:p:h:H:i:k:A:srS:d:g:G:lwz:M:t:T:c:C:DL:I:X:V");
if(opt < 0) if(opt < 0)
break; break;
...@@ -317,6 +319,9 @@ main(int argc, char **argv) ...@@ -317,6 +319,9 @@ main(int argc, char **argv)
fprintf(stderr, "%s\n", BABELD_VERSION); fprintf(stderr, "%s\n", BABELD_VERSION);
exit(0); exit(0);
break; break;
case 'X':
control_socket_path = optarg;
break;
default: default:
goto usage; goto usage;
} }
...@@ -536,6 +541,12 @@ main(int argc, char **argv) ...@@ -536,6 +541,12 @@ main(int argc, char **argv)
} }
} }
ctl_sockfd = init_control_socket();
if(ctl_sockfd < 0) {
perror("Couldn't create control socket");
goto fail;
}
init_signals(); init_signals();
rc = resize_receive_buffer(1500); rc = resize_receive_buffer(1500);
if(rc < 0) if(rc < 0)
...@@ -590,7 +601,8 @@ main(int argc, char **argv) ...@@ -590,7 +601,8 @@ main(int argc, char **argv)
while(1) { while(1) {
struct timeval tv; struct timeval tv;
fd_set readfds; fd_set readfds, writefds;
struct ctl *ctl, *ctl_next;
gettime(&now); gettime(&now);
...@@ -610,6 +622,7 @@ main(int argc, char **argv) ...@@ -610,6 +622,7 @@ main(int argc, char **argv)
} }
timeval_min(&tv, &unicast_flush_timeout); timeval_min(&tv, &unicast_flush_timeout);
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_ZERO(&writefds);
if(timeval_compare(&tv, &now) > 0) { if(timeval_compare(&tv, &now) > 0) {
int maxfd = 0; int maxfd = 0;
timeval_minus(&tv, &tv, &now); timeval_minus(&tv, &tv, &now);
...@@ -629,7 +642,16 @@ main(int argc, char **argv) ...@@ -629,7 +642,16 @@ main(int argc, char **argv)
FD_SET(local_sockets[i].fd, &readfds); FD_SET(local_sockets[i].fd, &readfds);
maxfd = MAX(maxfd, local_sockets[i].fd); maxfd = MAX(maxfd, local_sockets[i].fd);
} }
rc = select(maxfd + 1, &readfds, NULL, NULL, &tv); FD_SET(ctl_sockfd, &readfds);
maxfd = MAX(maxfd, ctl_sockfd);
for(ctl = ctl_connection; ctl; ctl = ctl->next) {
if(ctl->write < ctl->buffer_out.end)
FD_SET(ctl->fd, &writefds);
else
FD_SET(ctl->fd, &readfds);
maxfd = MAX(maxfd, ctl->fd);
}
rc = select(maxfd + 1, &readfds, &writefds, NULL, &tv);
if(rc < 0) { if(rc < 0) {
if(errno != EINTR) { if(errno != EINTR) {
perror("select"); perror("select");
...@@ -697,6 +719,16 @@ main(int argc, char **argv) ...@@ -697,6 +719,16 @@ main(int argc, char **argv)
i++; i++;
} }
if(FD_ISSET(ctl_sockfd, &readfds)) {
accept_ctl_connection(ctl_sockfd);
}
for(ctl = ctl_connection; ctl; ctl = ctl_next) {
ctl_next = ctl->next;
if (FD_ISSET(ctl->fd, &writefds))
ctl_write(ctl);
if (FD_ISSET(ctl->fd, &readfds))
ctl_read(ctl);
}
if(reopening) { if(reopening) {
kernel_dump_time = now.tv_sec; kernel_dump_time = now.tv_sec;
check_neighbours_timeout = now; check_neighbours_timeout = now;
...@@ -864,7 +896,7 @@ main(int argc, char **argv) ...@@ -864,7 +896,7 @@ main(int argc, char **argv)
" " " "
"[-u] [-t table] [-T table] [-c file] [-C statement]\n" "[-u] [-t table] [-T table] [-c file] [-C statement]\n"
" " " "
"[-d level] [-D] [-L logfile] [-I pidfile]\n" "[-d level] [-D] [-L logfile] [-I pidfile] [-X control-socket]\n"
" " " "
"interface...\n", "interface...\n",
BABELD_VERSION); BABELD_VERSION);
......
This diff is collapsed. Click to expand it.
/*
Copyright (c) 2014 Nexedi SA
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdint.h>
/* Soft limit to protect against misbehaviour,
* but feel free to increase it if needed. */
#define CTL_MAX_SIZE 65536
#define CTL_VERSION 1
#define CTL_MSG_DUMP 1
#define CTL_DUMP_INTERFACE (1 << 0)
#define CTL_DUMP_NEIGHBOUR (1 << 1)
#define CTL_DUMP_XROUTE (1 << 2)
#define CTL_DUMP_ROUTE(x) (x >> 3 & 3)
#define CTL_DUMP_ROUTE_NONE 0
#define CTL_DUMP_ROUTE_INSTALLED 1
#define CTL_DUMP_ROUTE_FEASIBLE 2
#define CTL_DUMP_ROUTE_ALL 3
#define CTL_ROUTE_INSTALLED (1 << 0)
#define CTL_ROUTE_FEASIBLE (1 << 1)
struct ctl_buffer {
char *data;
size_t size;
size_t end;
};
struct ctl_dump_neighbour {
uint8_t address[16];
uint32_t ifindex;
uint16_t reach;
uint16_t rxcost;
uint16_t txcost;
uint16_t rtt;
uint16_t rttcost;
int32_t channel;
uint16_t if_up;
} __attribute__((packed));
struct ctl_dump_route {
uint8_t prefix[16];
uint8_t plen;
uint16_t metric;
uint16_t smoothed_metric;
uint16_t refmetric;
uint8_t id[8];
int32_t seqno;
int32_t age;
uint32_t ifindex;
uint8_t neigh_address[16];
uint8_t nexthop[16];
uint8_t flags;
} __attribute__((packed));
struct ctl_dump_xroute {
uint8_t prefix[16];
uint8_t plen;
uint16_t metric;
} __attribute__((packed));
struct ctl {
struct ctl *next;
int fd;
struct ctl_buffer buffer_out;
struct ctl_buffer buffer_in;
size_t write;
unsigned initialized:1;
};
extern const char *control_socket_path;
extern struct ctl *ctl_connection;
int init_control_socket();
void accept_ctl_connection(int fd);
void ctl_read(struct ctl *ctl);
void ctl_write(struct ctl *ctl);
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!