From f51138dc4cd5aeba44a911e566a22f91640fac73 Mon Sep 17 00:00:00 2001 From: Grigorii Demidov Date: Tue, 11 Dec 2018 16:39:52 +0100 Subject: [PATCH] daemon/bindings: eBPF socket filter support, fix broken RHEL/CentOS build; fix callbacks for map_walk() --- daemon/bindings.c | 2 +- daemon/network.c | 42 ++++++++++++++++++++++++++++++++++-------- daemon/network.h | 2 +- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/daemon/bindings.c b/daemon/bindings.c index 917943e1e..d07723828 100644 --- a/daemon/bindings.c +++ b/daemon/bindings.c @@ -903,7 +903,7 @@ static int net_bpf_set(lua_State *L) } lua_pop(L, 1); - if (!network_set_bpf(net, progfd)) { + if (network_set_bpf(net, progfd) == 0) { char errmsg[256] = {}; snprintf(errmsg, sizeof(errmsg), "failed to attach BPF program to some networks: %s", strerror(errno)); format_error(L, errmsg); diff --git a/daemon/network.c b/daemon/network.c index 17cc92250..d7f5419fc 100644 --- a/daemon/network.c +++ b/daemon/network.c @@ -366,6 +366,7 @@ void network_new_hostname(struct network *net, struct engine *engine) static int set_bpf_cb(const char *key, void *val, void *ext) { +#ifdef SO_ATTACH_BPF endpoint_array_t *endpoints = (endpoint_array_t *)val; assert(endpoints != NULL); int *bpffd = (int *)ext; @@ -379,25 +380,37 @@ static int set_bpf_cb(const char *key, void *val, void *ext) assert(sockfd != -1); if (setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_BPF, bpffd, sizeof(int)) != 0) { - return 0; + return 1; /* return error (and stop iterating over net->endpoints) */ } } - +#else + kr_log_error("[network] SO_ATTACH_BPF socket option doesn't supported\n"); + (void)key; (void)val; (void)ext; return 1; +#endif + return 0; /* OK */ } -bool network_set_bpf(struct network *net, int bpf_fd) +int network_set_bpf(struct network *net, int bpf_fd) { - if (!map_walk(&net->endpoints, set_bpf_cb, &bpf_fd)) { +#ifdef SO_ATTACH_BPF + if (map_walk(&net->endpoints, set_bpf_cb, &bpf_fd) != 0) { + /* set_bpf_cb() has returned error. */ network_clear_bpf(net); return 0; } - +#else + kr_log_error("[network] SO_ATTACH_BPF socket option doesn't supported\n"); + (void)net; + (void)bpf_fd; + return 0; +#endif return 1; } static int clear_bpf_cb(const char *key, void *val, void *ext) { +#ifdef SO_DETACH_BPF endpoint_array_t *endpoints = (endpoint_array_t *)val; assert(endpoints != NULL); @@ -408,13 +421,26 @@ static int clear_bpf_cb(const char *key, void *val, void *ext) if (endpoint->udp != NULL) uv_fileno((const uv_handle_t *)endpoint->udp, &sockfd); assert(sockfd != -1); - setsockopt(sockfd, SOL_SOCKET, SO_DETACH_BPF, NULL, 0); + if (setsockopt(sockfd, SOL_SOCKET, SO_DETACH_BPF, NULL, 0) != 0) { + kr_log_error("[network] failed to clear SO_DETACH_BPF socket option\n"); + } + /* Proceed even if setsockopt() failed, + * as we want to process all opened sockets. */ } - +#else + kr_log_error("[network] SO_DETACH_BPF socket option doesn't supported\n"); + (void)key; (void)val; (void)ext; return 1; +#endif + return 0; } void network_clear_bpf(struct network *net) { - assert(map_walk(&net->endpoints, clear_bpf_cb, NULL)); +#ifdef SO_DETACH_BPF + map_walk(&net->endpoints, clear_bpf_cb, NULL); +#else + kr_log_error("[network] SO_DETACH_BPF socket option doesn't supported\n"); + (void)net; +#endif } diff --git a/daemon/network.h b/daemon/network.h index 1554f44b9..11e1febae 100644 --- a/daemon/network.h +++ b/daemon/network.h @@ -66,5 +66,5 @@ int network_close(struct network *net, const char *addr, uint16_t port); int network_set_tls_cert(struct network *net, const char *cert); int network_set_tls_key(struct network *net, const char *key); void network_new_hostname(struct network *net, struct engine *engine); -bool network_set_bpf(struct network *net, int bpf_fd); +int network_set_bpf(struct network *net, int bpf_fd); void network_clear_bpf(struct network *net); -- 2.47.2