ubus: add api for providing dns lookup results for dns regex rules
authorFelix Fietkau <nbd@nbd.name>
Wed, 3 Nov 2021 14:24:58 +0000 (15:24 +0100)
committerFelix Fietkau <nbd@nbd.name>
Wed, 3 Nov 2021 14:24:58 +0000 (15:24 +0100)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
map.c
qosify.h
ubus.c

diff --git a/map.c b/map.c
index 7f8c20dcb0c215656a19da58c3c1a30296e8b490..41db52d2f0c5bff34e64334d36ffe320d300573f 100644 (file)
--- a/map.c
+++ b/map.c
@@ -585,6 +585,52 @@ void qosify_map_gc(void)
        uloop_timeout_set(&qosify_map_timer, timeout * 1000);
 }
 
+
+int qosify_map_add_dns_host(const char *host, const char *addr, const char *type, int ttl)
+{
+       struct qosify_map_data data = {
+               .id = CL_MAP_DNS,
+               .addr.dns.pattern = "",
+       };
+       struct qosify_map_entry *e;
+       int prev_timeout = qosify_map_timeout;
+
+       e = avl_find_ge_element(&map_data, &data, e, avl);
+       if (!e)
+               return 0;
+
+       memset(&data, 0, sizeof(data));
+       data.user = true;
+       if (!strcmp(type, "A"))
+               data.id = CL_MAP_IPV4_ADDR;
+       else if (!strcmp(type, "AAAA"))
+               data.id = CL_MAP_IPV6_ADDR;
+       else
+               return 0;
+
+       if (qosify_map_fill_ip(&data, addr))
+               return -1;
+
+       avl_for_element_to_last(&map_data, e, e, avl) {
+               regex_t *regex = &e->data.addr.dns.regex;
+
+               if (e->data.id != CL_MAP_DNS)
+                       return 0;
+
+               if (regexec(regex, host, 0, NULL, 0) != 0)
+                       continue;
+
+               if (ttl)
+                       qosify_map_timeout = ttl;
+               data.dscp = e->data.dscp;
+               __qosify_map_set_entry(&data);
+               qosify_map_timeout = prev_timeout;
+       }
+
+       return 0;
+}
+
+
 void qosify_map_dump(struct blob_buf *b)
 {
        struct qosify_map_entry *e;
index 285543a6bc73f53743053924a939dc140cce4f71..f9d8026b6acc30c71ccb723f76a2786330f7b564 100644 (file)
--- a/qosify.h
+++ b/qosify.h
@@ -79,6 +79,7 @@ void qosify_map_dump(struct blob_buf *b);
 void qosify_map_set_dscp_default(enum qosify_map_id id, uint8_t val);
 void qosify_map_reset_config(void);
 void qosify_map_update_config(void);
+int qosify_map_add_dns_host(const char *host, const char *addr, const char *type, int ttl);
 
 int qosify_iface_init(void);
 void qosify_iface_config_update(struct blob_attr *ifaces, struct blob_attr *devs);
diff --git a/ubus.c b/ubus.c
index 66200c1f7808618d6dc44a6ff0cf59ee5fcb0dea..79ad9572a608fd76badaf90714cc3966305e30d1 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -268,6 +268,48 @@ qosify_ubus_check_devices(struct ubus_context *ctx, struct ubus_object *obj,
        return 0;
 }
 
+enum {
+       CL_DNS_HOST_NAME,
+       CL_DNS_HOST_TYPE,
+       CL_DNS_HOST_ADDR,
+       CL_DNS_HOST_TTL,
+       __CL_DNS_HOST_MAX
+};
+
+static const struct blobmsg_policy qosify_dns_policy[__CL_DNS_HOST_MAX] = {
+       [CL_DNS_HOST_NAME] = { "name", BLOBMSG_TYPE_STRING },
+       [CL_DNS_HOST_TYPE] = { "type", BLOBMSG_TYPE_STRING },
+       [CL_DNS_HOST_ADDR] = { "address", BLOBMSG_TYPE_STRING },
+       [CL_DNS_HOST_TTL] = { "ttl", BLOBMSG_TYPE_INT32 },
+};
+
+static int
+qosify_ubus_add_dns_host(struct ubus_context *ctx, struct ubus_object *obj,
+                        struct ubus_request_data *req, const char *method,
+                        struct blob_attr *msg)
+{
+       struct blob_attr *tb[__CL_DNS_HOST_MAX];
+       struct blob_attr *cur;
+       uint32_t ttl = 0;
+
+       blobmsg_parse(qosify_dns_policy, __CL_DNS_HOST_MAX, tb,
+                     blobmsg_data(msg), blobmsg_len(msg));
+
+       if (!tb[CL_DNS_HOST_NAME] || !tb[CL_DNS_HOST_TYPE] ||
+           !tb[CL_DNS_HOST_ADDR])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if ((cur = tb[CL_DNS_HOST_TTL]) != NULL)
+               ttl = blobmsg_get_u32(cur);
+
+       if (qosify_map_add_dns_host(blobmsg_get_string(tb[CL_DNS_HOST_NAME]),
+                                   blobmsg_get_string(tb[CL_DNS_HOST_ADDR]),
+                                   blobmsg_get_string(tb[CL_DNS_HOST_TYPE]),
+                                   ttl))
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+       return 0;
+}
 
 static const struct ubus_method qosify_methods[] = {
        UBUS_METHOD_NOARG("reload", qosify_ubus_reload),
@@ -277,6 +319,7 @@ static const struct ubus_method qosify_methods[] = {
        UBUS_METHOD("config", qosify_ubus_config, qosify_config_policy),
        UBUS_METHOD_NOARG("dump", qosify_ubus_dump),
        UBUS_METHOD_NOARG("status", qosify_ubus_status),
+       UBUS_METHOD("add_dns_host", qosify_ubus_add_dns_host, qosify_dns_policy),
        UBUS_METHOD_NOARG("check_devices", qosify_ubus_check_devices),
 };