From: Daniel Salzman Date: Fri, 10 Apr 2020 16:16:28 +0000 (+0200) Subject: knotd: add XDP message context to qdata, fix module queryacl X-Git-Tag: embedded_lmdb~35^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb39584314acd6db9591e3224ddc1902ce8e2590;p=thirdparty%2Fknot-dns.git knotd: add XDP message context to qdata, fix module queryacl --- diff --git a/src/knot/include/module.h b/src/knot/include/module.h index 4020cf4b36..9ca02028d6 100644 --- a/src/knot/include/module.h +++ b/src/knot/include/module.h @@ -36,7 +36,7 @@ /*** Query module API. ***/ /*! Current module ABI version. */ -#define KNOTD_MOD_ABI_VERSION 200 +#define KNOTD_MOD_ABI_VERSION 300 /*! Module configuration name prefix. */ #define KNOTD_MOD_NAME_PREFIX "mod-" @@ -380,7 +380,6 @@ typedef enum { KNOTD_QUERY_FLAG_LIMIT_ANY = 1 << 2, /*!< Limit ANY QTYPE (respond with TC=1). */ KNOTD_QUERY_FLAG_LIMIT_SIZE = 1 << 3, /*!< Apply UDP size limit. */ KNOTD_QUERY_FLAG_COOKIE = 1 << 4, /*!< Valid DNS Cookie indication. */ - KNOTD_QUERY_FLAG_XDP = 1 << 5, /*!< Processing over XDP indication. */ } knotd_query_flag_t; /*! Query processing data context parameters. */ @@ -390,6 +389,7 @@ typedef struct { int socket; /*!< Current network socket. */ unsigned thread_id; /*!< Current thread id. */ void *server; /*!< Server object private item. */ + struct knot_xdp_msg *xdp_msg; /*!< Possible XDP message context. */ } knotd_qdata_params_t; /*! Query processing data context. */ diff --git a/src/knot/modules/queryacl/queryacl.c b/src/knot/modules/queryacl/queryacl.c index 38a4f3c75e..03633ffb27 100644 --- a/src/knot/modules/queryacl/queryacl.c +++ b/src/knot/modules/queryacl/queryacl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 CZ.NIC, z.s.p.o. +/* Copyright (C) 2020 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,14 +43,6 @@ static knotd_state_t queryacl_process(knotd_state_t state, knot_pkt_t *pkt, return state; } - // Get interface address. - struct sockaddr_storage iface; - socklen_t iface_len = sizeof(iface); - if (getsockname(qdata->params->socket, (struct sockaddr *)&iface, &iface_len) != 0) { - knotd_mod_log(mod, LOG_ERR, "failed to get interface address"); - return KNOTD_STATE_FAIL; - } - if (ctx->allow_addr.count > 0) { if (!knotd_conf_addr_range_match(&ctx->allow_addr, qdata->params->remote)) { qdata->rcode = KNOT_RCODE_NOTAUTH; @@ -59,7 +51,27 @@ static knotd_state_t queryacl_process(knotd_state_t state, knot_pkt_t *pkt, } if (ctx->allow_iface.count > 0) { - if (!knotd_conf_addr_range_match(&ctx->allow_iface, &iface)) { + struct sockaddr_storage iface; + socklen_t iface_len = sizeof(iface); + struct sockaddr_storage *iface_ptr; + + if (qdata->params->xdp_msg != NULL) { +#ifdef ENABLE_XDP + iface_ptr = (struct sockaddr_storage *)&qdata->params->xdp_msg->ip_to; +#else + assert(0); + return KNOTD_STATE_FAIL; +#endif + } else { + if (getsockname(qdata->params->socket, (struct sockaddr *)&iface, + &iface_len) != 0) { + knotd_mod_log(mod, LOG_ERR, "failed to get interface address"); + return KNOTD_STATE_FAIL; + } + iface_ptr = &iface; + } + + if (!knotd_conf_addr_range_match(&ctx->allow_iface, iface_ptr)) { qdata->rcode = KNOT_RCODE_NOTAUTH; return KNOTD_STATE_FAIL; } diff --git a/src/knot/modules/stats/stats.c b/src/knot/modules/stats/stats.c index fccf7c39df..84d9d77f26 100644 --- a/src/knot/modules/stats/stats.c +++ b/src/knot/modules/stats/stats.c @@ -490,7 +490,7 @@ static knotd_state_t update_counters(knotd_state_t state, knot_pkt_t *pkt, // Count the request protocol. if (stats->protocol) { - bool xdp = qdata->params->flags & KNOTD_QUERY_FLAG_XDP; + bool xdp = qdata->params->xdp_msg != NULL; if (qdata->params->remote->ss_family == AF_INET) { if (qdata->params->flags & KNOTD_QUERY_FLAG_LIMIT_SIZE) { if (xdp) { diff --git a/src/knot/server/udp-handler.c b/src/knot/server/udp-handler.c index 74a16e0405..72ecee7885 100644 --- a/src/knot/server/udp-handler.c +++ b/src/knot/server/udp-handler.c @@ -59,17 +59,17 @@ static bool udp_state_active(int state) } static void udp_handle(udp_context_t *udp, int fd, struct sockaddr_storage *ss, - struct iovec *rx, struct iovec *tx, bool use_xdp) + struct iovec *rx, struct iovec *tx, struct knot_xdp_msg *xdp_msg) { /* Create query processing parameter. */ knotd_qdata_params_t params = { .remote = ss, .flags = KNOTD_QUERY_FLAG_NO_AXFR | KNOTD_QUERY_FLAG_NO_IXFR | /* No transfers. */ KNOTD_QUERY_FLAG_LIMIT_SIZE | /* Enforce UDP packet size limit. */ - KNOTD_QUERY_FLAG_LIMIT_ANY | /* Limit ANY over UDP (depends on zone as well). */ - (use_xdp ? KNOTD_QUERY_FLAG_XDP : 0), /* Mark XDP processing. */ + KNOTD_QUERY_FLAG_LIMIT_ANY, /* Limit ANY over UDP (depends on zone as well). */ .socket = fd, .server = udp->server, + .xdp_msg = xdp_msg, .thread_id = udp->thread_id }; @@ -213,7 +213,7 @@ static int udp_recvfrom_handle(udp_context_t *ctx, void *d, void *unused) udp_pktinfo_handle(&rq->msg[RX], &rq->msg[TX]); /* Process received pkt. */ - udp_handle(ctx, rq->fd, &rq->addr, &rq->iov[RX], &rq->iov[TX], false); + udp_handle(ctx, rq->fd, &rq->addr, &rq->iov[RX], &rq->iov[TX], NULL); return KNOT_EOK; } @@ -321,7 +321,7 @@ static int udp_recvmmsg_handle(udp_context_t *ctx, void *d, void *unused) udp_pktinfo_handle(&rq->msgs[RX][i].msg_hdr, &rq->msgs[TX][i].msg_hdr); - udp_handle(ctx, rq->fd, rq->addrs + i, rx, tx, false); + udp_handle(ctx, rq->fd, rq->addrs + i, rx, tx, NULL); rq->msgs[TX][i].msg_len = tx->iov_len; rq->msgs[TX][i].msg_hdr.msg_namelen = 0; if (tx->iov_len > 0) { @@ -416,7 +416,8 @@ static int xdp_recvmmsg_handle(udp_context_t *ctx, void *d, void *xdp_sock) udp_handle(ctx, knot_xdp_socket_fd(xdp_sock), (struct sockaddr_storage *)&rq->msgs_rx[i].ip_from, - &rq->msgs_rx[i].payload, &rq->msgs_tx[i].payload, true); + &rq->msgs_rx[i].payload, &rq->msgs_tx[i].payload, + &rq->msgs_rx[i]); responses++; } diff --git a/src/libknot/xdp/xdp.h b/src/libknot/xdp/xdp.h index dc0538666c..f6408f3234 100644 --- a/src/libknot/xdp/xdp.h +++ b/src/libknot/xdp/xdp.h @@ -28,13 +28,14 @@ #endif /*! \brief A packet with src & dst MAC & IP addrs + UDP payload. */ -typedef struct { +typedef struct knot_xdp_msg knot_xdp_msg_t; +struct knot_xdp_msg { struct sockaddr_in6 ip_from; struct sockaddr_in6 ip_to; uint8_t *eth_from; uint8_t *eth_to; struct iovec payload; -} knot_xdp_msg_t; +}; /*! * \brief Styles of loading BPF program.