]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/bindings: eBPF socket filter support, fix broken RHEL/CentOS build; fix callba...
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Tue, 11 Dec 2018 15:39:52 +0000 (16:39 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Thu, 13 Dec 2018 11:26:38 +0000 (11:26 +0000)
daemon/bindings.c
daemon/network.c
daemon/network.h

index 917943e1ec7e9c8029b22b8d2c3518edfc182772..d0772382859fa3bf1141db2f84981e87a5b4b6bf 100644 (file)
@@ -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);
index 17cc92250388ad72f81fab895a629c6dfe3b46b4..d7f5419fc8d377e7c5bbae32f944b6b63fb89630 100644 (file)
@@ -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
 }
index 1554f44b9d3798f5faf637815974906c022b7d74..11e1febae247e81c07fd1c35624934c5ed69bf55 100644 (file)
@@ -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);