/*** 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-"
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. */
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. */
-/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
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
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;
}
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;
}
// 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) {
}
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
};
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;
}
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) {
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++;
}
#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.