static LIST_HEAD(map_files);
static uint32_t next_timeout;
static uint8_t qosify_dscp_default[2] = { 0xff, 0xff };
-int qosify_map_timeout = 3600;
+int qosify_map_timeout;
+int qosify_active_timeout;
struct qosify_config config;
struct qosify_map_file {
{ "AF43", 38 },
{ "EF", 46 },
{ "VA", 44 },
+ { "LE", 1 },
+ { "DF", 0 },
};
static void qosify_map_timer_cb(struct uloop_timeout *t)
e->data.dscp = e->data.file_dscp;
}
- if (e->data.dscp != prev_dscp && data->id < CL_MAP_DNS)
- bpf_map_update_elem(fd, &data->addr, &e->data.dscp, BPF_ANY);
+ if (e->data.dscp != prev_dscp && data->id < CL_MAP_DNS) {
+ struct qosify_ip_map_val val = {
+ .dscp = e->data.dscp,
+ .seen = 1,
+ };
+
+ bpf_map_update_elem(fd, &data->addr, &val, BPF_ANY);
+ }
if (add) {
if (qosify_map_timeout == ~0 || file) {
qosify_map_set_dscp_default(CL_MAP_TCP_PORTS, 0);
qosify_map_set_dscp_default(CL_MAP_UDP_PORTS, 0);
qosify_map_timeout = 3600;
+ qosify_active_timeout = 300;
memset(&config, 0, sizeof(config));
config.dscp_prio = 0xff;
free(e);
}
+static bool
+qosify_map_entry_refresh_timeout(struct qosify_map_entry *e)
+{
+ struct qosify_ip_map_val val;
+ int fd = qosify_map_fds[e->data.id];
+
+ if (e->data.id != CL_MAP_IPV4_ADDR &&
+ e->data.id != CL_MAP_IPV6_ADDR)
+ return false;
+
+ if (bpf_map_lookup_elem(fd, &e->data.addr, &val))
+ return false;
+
+ if (!val.seen)
+ return false;
+
+ e->timeout = qosify_gettime() + qosify_active_timeout;
+ val.seen = 0;
+ bpf_map_update_elem(fd, &e->data.addr, &val, BPF_ANY);
+
+ return true;
+}
+
void qosify_map_gc(void)
{
struct qosify_map_entry *e, *tmp;
if (e->data.user && e->timeout != ~0) {
cur_timeout = e->timeout - cur_time;
+ if (cur_timeout <= 0 &&
+ qosify_map_entry_refresh_timeout(e))
+ cur_timeout = e->timeout - cur_time;
if (cur_timeout <= 0) {
e->data.user = false;
e->data.dscp = e->data.file_dscp;
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;