From 2ca70171e692718c6fe9c011858719e9fb5242fb Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Wed, 28 Nov 2018 22:40:46 +0100 Subject: [PATCH] Allow to independently monitor and dump events for neighbour, interface, route, xroute In large networks there is much traffic on the socket. This induces high load even when only a subset of the data is relevant. This commit introduces new commands on the socket for: * (un)monitor neighbour * (un)monitor route * (un)monitor xroute, * (un)monitor interface * dump neighbour * dump route * dump xroute * dump interface that will exclusively show changes for these structures or disable showing specific changes. --- babeld.man | 15 +++---- configuration.c | 65 ++++++++++++++++++++++++++----- configuration.h | 18 +++++++-- local.c | 101 ++++++++++++++++++++++++++++++++++++++++-------- local.h | 8 +++- 5 files changed, 167 insertions(+), 40 deletions(-) diff --git a/babeld.man b/babeld.man index 8c865d24..675811f5 100644 --- a/babeld.man +++ b/babeld.man @@ -594,20 +594,15 @@ replies with one or more lines of data terminated by one of or .BR bad . -The following requests are currently defined: +All configuration file directives are valid socket requests, including: .IP \(bu 2 -any configuration file directive, including -.BR interface ; +.BR "[flush] interface" .IP \(bu -.BR "flush interface" ; +.BR "dump [neighbour|route|xroute|interface]" .IP \(bu -.BR dump ; +.BR "[un]monitor [neighbour|route|xroute|interface]" .IP \(bu -.B monitor -and -.BR unmonitor ; -.IP \(bu -.BR quit . +.BR quit .SH EXAMPLES You can participate in a Babel network by simply running .IP diff --git a/configuration.c b/configuration.c index 3b554f56..fe4fcf47 100644 --- a/configuration.c +++ b/configuration.c @@ -1127,20 +1127,65 @@ parse_config_line(int c, gnc_t gnc, void *closure, goto fail; *action_return = CONFIG_ACTION_QUIT; } else if(strcmp(token, "dump") == 0) { - c = skip_eol(c, gnc, closure); - if(c < -1 || !action_return) - goto fail; *action_return = CONFIG_ACTION_DUMP; + char *token2 = NULL; + c = skip_whitespace(c, gnc, closure); + c = getword(c, &token2, gnc, closure); + if (token2) + { + if (strcmp(token2, "route") == 0) + *action_return = CONFIG_ACTION_DUMP_ROUTE; + else if (strcmp(token2, "interface") == 0) + *action_return = CONFIG_ACTION_DUMP_INTERFACE; + else if (strcmp(token2, "xroute") == 0) + *action_return = CONFIG_ACTION_DUMP_XROUTE; + else if (strcmp(token2, "neighbour") == 0) + *action_return = CONFIG_ACTION_DUMP_NEIGHBOUR; + free(token2); + c = skip_eol(c, gnc, closure); + } + else + c = -1; } else if(strcmp(token, "monitor") == 0) { - c = skip_eol(c, gnc, closure); - if(c < -1 || !action_return) - goto fail; - *action_return = CONFIG_ACTION_MONITOR; + *action_return = CONFIG_ACTION_MONITOR; + char *token2 = NULL; + c = skip_whitespace(c, gnc, closure); + c = getword(c, &token2, gnc, closure); + if (token2) + { + if (strcmp(token2, "route") == 0) + *action_return = CONFIG_ACTION_MONITOR_ROUTE; + else if (strcmp(token2, "interface") == 0) + *action_return = CONFIG_ACTION_MONITOR_INTERFACE; + else if (strcmp(token2, "xroute") == 0) + *action_return = CONFIG_ACTION_MONITOR_XROUTE; + else if (strcmp(token2, "neighbour") == 0) + *action_return = CONFIG_ACTION_MONITOR_NEIGHBOUR; + free(token2); + c = skip_eol(c, gnc, closure); + } + else + c = -1; } else if(strcmp(token, "unmonitor") == 0) { - c = skip_eol(c, gnc, closure); - if(c < -1 || !action_return) - goto fail; *action_return = CONFIG_ACTION_UNMONITOR; + char *token2 = NULL; + c = skip_whitespace(c, gnc, closure); + c = getword(c, &token2, gnc, closure); + if (token2) + { + if (strcmp(token2, "route") == 0) + *action_return = CONFIG_ACTION_UNMONITOR_ROUTE; + else if (strcmp(token2, "interface") == 0) + *action_return = CONFIG_ACTION_UNMONITOR_INTERFACE; + else if (strcmp(token2, "xroute") == 0) + *action_return = CONFIG_ACTION_UNMONITOR_XROUTE; + else if (strcmp(token2, "neighbour") == 0) + *action_return = CONFIG_ACTION_UNMONITOR_NEIGHBOUR; + free(token2); + c = skip_eol(c, gnc, closure); + } + else // ummonitor was detected but none of the specialties - unmonitoring everything. + c = -1; } else if(config_finalised && !local_server_write) { /* The remaining directives are only allowed in read-write mode. */ c = skip_to_eol(c, gnc, closure); diff --git a/configuration.h b/configuration.h index 95ce16cc..738870c2 100644 --- a/configuration.h +++ b/configuration.h @@ -25,9 +25,21 @@ THE SOFTWARE. #define CONFIG_ACTION_DONE 0 #define CONFIG_ACTION_QUIT 1 #define CONFIG_ACTION_DUMP 2 -#define CONFIG_ACTION_MONITOR 3 -#define CONFIG_ACTION_UNMONITOR 4 -#define CONFIG_ACTION_NO 5 +#define CONFIG_ACTION_DUMP_NEIGHBOUR 3 +#define CONFIG_ACTION_DUMP_ROUTE 4 +#define CONFIG_ACTION_DUMP_XROUTE 5 +#define CONFIG_ACTION_DUMP_INTERFACE 6 +#define CONFIG_ACTION_MONITOR 7 +#define CONFIG_ACTION_UNMONITOR 8 +#define CONFIG_ACTION_NO 9 +#define CONFIG_ACTION_MONITOR_NEIGHBOUR 10 +#define CONFIG_ACTION_UNMONITOR_NEIGHBOUR 11 +#define CONFIG_ACTION_MONITOR_ROUTE 12 +#define CONFIG_ACTION_UNMONITOR_ROUTE 13 +#define CONFIG_ACTION_MONITOR_XROUTE 14 +#define CONFIG_ACTION_UNMONITOR_XROUTE 15 +#define CONFIG_ACTION_MONITOR_INTERFACE 16 +#define CONFIG_ACTION_UNMONITOR_INTERFACE 17 #define AUTH_TYPE_NONE 0 #define AUTH_TYPE_SHA256 1 diff --git a/local.c b/local.c index bf3de623..d6279af5 100644 --- a/local.c +++ b/local.c @@ -133,7 +133,7 @@ local_notify_interface(struct interface *ifp, int kind) { int i; for(i = 0; i < num_local_sockets; i++) { - if(local_sockets[i].monitor) + if(local_sockets[i].monitor & (0x01 << SHOW_INTERFACE)) local_notify_interface_1(&local_sockets[i], ifp, kind); } } @@ -188,7 +188,7 @@ local_notify_neighbour(struct neighbour *neigh, int kind) { int i; for(i = 0; i < num_local_sockets; i++) { - if(local_sockets[i].monitor) + if(local_sockets[i].monitor & (0x01 << SHOW_NEIGHBOUR)) local_notify_neighbour_1(&local_sockets[i], neigh, kind); } } @@ -225,7 +225,7 @@ local_notify_xroute(struct xroute *xroute, int kind) { int i; for(i = 0; i < num_local_sockets; i++) { - if(local_sockets[i].monitor) + if(local_sockets[i].monitor & (0x01 << SHOW_XROUTE)) local_notify_xroute_1(&local_sockets[i], xroute, kind); } } @@ -270,26 +270,36 @@ local_notify_route(struct babel_route *route, int kind) { int i; for(i = 0; i < num_local_sockets; i++) { - if(local_sockets[i].monitor) + if(local_sockets[i].monitor & (0x01 << SHOW_ROUTE)) local_notify_route_1(&local_sockets[i], route, kind); } } + static void -local_notify_all_1(struct local_socket *s) +local_notify_all_neighbour_1(struct local_socket *s) { - struct interface *ifp; struct neighbour *neigh; - struct xroute_stream *xroutes; - struct route_stream *routes; + + FOR_ALL_NEIGHBOURS(neigh) { + local_notify_neighbour_1(s, neigh, LOCAL_ADD); + } +} + +static void +local_notify_all_interface_1(struct local_socket *s) +{ + struct interface *ifp; FOR_ALL_INTERFACES(ifp) { local_notify_interface_1(s, ifp, LOCAL_ADD); } +} - FOR_ALL_NEIGHBOURS(neigh) { - local_notify_neighbour_1(s, neigh, LOCAL_ADD); - } +static void +local_notify_all_xroute_1(struct local_socket *s) +{ + struct xroute_stream *xroutes; xroutes = xroute_stream(); if(xroutes) { @@ -301,6 +311,12 @@ local_notify_all_1(struct local_socket *s) } xroute_stream_done(xroutes); } +} + +static void +local_notify_all_route_1(struct local_socket *s) +{ + struct route_stream *routes; routes = route_stream(0); if(routes) { @@ -312,7 +328,48 @@ local_notify_all_1(struct local_socket *s) } route_stream_done(routes); } - return; +} + +static void +local_notify_all(struct local_socket *s, unsigned int mask) +{ + if(mask & (0x01 << SHOW_INTERFACE)) + local_notify_all_interface_1(s); + if(mask & (0x01 << SHOW_NEIGHBOUR)) + local_notify_all_neighbour_1(s); + if(mask & (0x01 << SHOW_XROUTE)) + local_notify_all_xroute_1(s); + if(mask & (0x01 << SHOW_ROUTE)) + local_notify_all_route_1(s); +} + + +static unsigned int +show_flags_map(int rc) +{ + switch(rc) { + case CONFIG_ACTION_MONITOR_ROUTE: + case CONFIG_ACTION_UNMONITOR_ROUTE: + case CONFIG_ACTION_DUMP_ROUTE: + return 0x01 << SHOW_ROUTE; + case CONFIG_ACTION_MONITOR_INTERFACE: + case CONFIG_ACTION_UNMONITOR_INTERFACE: + case CONFIG_ACTION_DUMP_INTERFACE: + return 0x01 << SHOW_INTERFACE; + case CONFIG_ACTION_MONITOR_XROUTE: + case CONFIG_ACTION_UNMONITOR_XROUTE: + case CONFIG_ACTION_DUMP_XROUTE: + return 0x01 << SHOW_XROUTE; + case CONFIG_ACTION_MONITOR_NEIGHBOUR: + case CONFIG_ACTION_UNMONITOR_NEIGHBOUR: + case CONFIG_ACTION_DUMP_NEIGHBOUR: + return 0x01 << SHOW_NEIGHBOUR; + case CONFIG_ACTION_MONITOR: + case CONFIG_ACTION_UNMONITOR: + case CONFIG_ACTION_DUMP: + return 0xff; + } + return 0; } int @@ -352,15 +409,27 @@ local_read(struct local_socket *s) shutdown(s->fd, 1); reply[0] = '\0'; break; + case CONFIG_ACTION_DUMP_INTERFACE: + case CONFIG_ACTION_DUMP_ROUTE: + case CONFIG_ACTION_DUMP_XROUTE: + case CONFIG_ACTION_DUMP_NEIGHBOUR: case CONFIG_ACTION_DUMP: - local_notify_all_1(s); + local_notify_all(s, show_flags_map(rc)); break; + case CONFIG_ACTION_MONITOR_INTERFACE: + case CONFIG_ACTION_MONITOR_ROUTE: + case CONFIG_ACTION_MONITOR_XROUTE: + case CONFIG_ACTION_MONITOR_NEIGHBOUR: case CONFIG_ACTION_MONITOR: - local_notify_all_1(s); - s->monitor = 1; + s->monitor |= show_flags_map(rc); + local_notify_all(s, show_flags_map(rc)); break; + case CONFIG_ACTION_UNMONITOR_INTERFACE: + case CONFIG_ACTION_UNMONITOR_ROUTE: + case CONFIG_ACTION_UNMONITOR_XROUTE: + case CONFIG_ACTION_UNMONITOR_NEIGHBOUR: case CONFIG_ACTION_UNMONITOR: - s->monitor = 0; + s->monitor &= ~show_flags_map(rc); break; case CONFIG_ACTION_NO: snprintf(reply, sizeof(reply), "no%s%s\n", diff --git a/local.h b/local.h index 23161111..9d3929ed 100644 --- a/local.h +++ b/local.h @@ -38,9 +38,15 @@ struct local_socket { int fd; char *buf; int n; - int monitor; + unsigned int monitor; }; +#define SHOW_NEIGHBOUR 1 +#define SHOW_INTERFACE 2 +#define SHOW_ROUTE 3 +#define SHOW_XROUTE 4 + + extern int local_server_socket; extern struct local_socket local_sockets[MAX_LOCAL_SOCKETS]; extern int num_local_sockets;