dns: allow limiting dns entry matching to cname name
[project/qosify.git] / interface.c
index 3f3bd304452b7dce894f9f5e202e982f65f9b752..7d9cecd76d11e205c60749a0063e07071ffc37cb 100644 (file)
@@ -4,7 +4,6 @@
  */
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/wait.h>
 #include <sys/ioctl.h>
 #include <net/if_arp.h>
 #include <net/if.h>
@@ -149,7 +148,7 @@ iface_config_set(struct qosify_iface *iface, struct blob_attr *attr)
        cfg->ingress = true;
        cfg->egress = true;
        cfg->host_isolate = true;
-       cfg->autorate_ingress = true;
+       cfg->autorate_ingress = false;
        cfg->nat = !iface->device;
 
        if ((cur = tb[IFACE_ATTR_BW_UP]) != NULL)
@@ -195,64 +194,6 @@ interface_ifb_name(struct qosify_iface *iface)
        return ifname;
 }
 
-static int run_cmd(char *cmd, bool ignore)
-{
-       char *argv[] = { "sh", "-c", cmd, NULL };
-       bool first = true;
-       int status = -1;
-       char buf[512];
-       int fds[2];
-       FILE *f;
-       int pid;
-
-       if (pipe(fds))
-               return -1;
-
-       pid = fork();
-       if (!pid) {
-               close(fds[0]);
-               if (fds[1] != STDOUT_FILENO)
-                       dup2(fds[1], STDOUT_FILENO);
-               if (fds[1] != STDERR_FILENO)
-                       dup2(fds[1], STDERR_FILENO);
-               if (fds[1] > STDERR_FILENO)
-                       close(fds[1]);
-               execv("/bin/sh", argv);
-               exit(1);
-       }
-
-       if (pid < 0)
-               return -1;
-
-       close(fds[1]);
-       f = fdopen(fds[0], "r");
-       if (!f) {
-               close(fds[0]);
-               goto out;
-       }
-
-       while (fgets(buf, sizeof(buf), f) != NULL) {
-               if (!strlen(buf))
-                       break;
-               if (ignore)
-                       continue;
-               if (first) {
-                       ULOG_WARN("Command: %s\n", cmd);
-                       first = false;
-               }
-               ULOG_WARN("%s%s", buf, strchr(buf, '\n') ? "" : "\n");
-       }
-
-       fclose(f);
-
-out:
-       while (waitpid(pid, &status, 0) < 0)
-               if (errno != EINTR)
-                       break;
-
-       return status;
-}
-
 static int
 prepare_tc_cmd(char *buf, int len, const char *type, const char *cmd,
               const char *dev, const char *extra)
@@ -267,7 +208,7 @@ cmd_del_qdisc(const char *ifname, const char *type)
 
        prepare_tc_cmd(buf, sizeof(buf), "qdisc", "del", ifname, type);
 
-       return run_cmd(buf, true);
+       return qosify_run_cmd(buf, true);
 }
 
 static int
@@ -286,6 +227,8 @@ cmd_add_qdisc(struct qosify_iface *iface, const char *ifname, bool egress, bool
                APPEND(buf, ofs, " bandwidth %s", bw);
 
        APPEND(buf, ofs, " %s %sgress", cfg->mode, egress ? "e" : "in");
+       if (!egress && cfg->autorate_ingress)
+               APPEND(buf, ofs, " autorate-ingress");
 
        if (cfg->host_isolate)
                APPEND(buf, ofs, " %snat dual-%shost",
@@ -298,14 +241,14 @@ cmd_add_qdisc(struct qosify_iface *iface, const char *ifname, bool egress, bool
               cfg->common_opts ? cfg->common_opts : "",
               dir_opts ? dir_opts : "");
 
-       run_cmd(buf, false);
+       qosify_run_cmd(buf, false);
 
        ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", ifname, "parent 1: bpf");
        APPEND(buf, ofs, " object-pinned /sys/fs/bpf/qosify_%sgress_%s verbose direct-action",
               egress ? "e" : "in",
                   eth ? "eth" : "ip");
 
-       return run_cmd(buf, false);
+       return qosify_run_cmd(buf, false);
 }
 
 static int
@@ -316,7 +259,7 @@ cmd_del_ingress(struct qosify_iface *iface)
        cmd_del_qdisc(iface->ifname, "handle ffff: ingress");
        snprintf(buf, sizeof(buf), "ip link del '%s'", interface_ifb_name(iface));
 
-       return run_cmd(buf, true);
+       return qosify_run_cmd(buf, true);
 }
 
 
@@ -330,20 +273,33 @@ cmd_add_ingress(struct qosify_iface *iface, bool eth)
        cmd_del_ingress(iface);
 
        ofs = prepare_tc_cmd(buf, sizeof(buf), "qdisc", "add", iface->ifname, " handle ffff: ingress");
-       run_cmd(buf, false);
+       qosify_run_cmd(buf, false);
+
+       ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " parent ffff:");
+       APPEND(buf, ofs, " protocol ip prio 5 u32 match ip sport 53 0xffff "
+                        "flowid 1:1 action mirred egress redirect dev ifb-dns");
+       qosify_run_cmd(buf, false);
+
+       ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " parent ffff:");
+       APPEND(buf, ofs, " protocol ipv6 prio 6 u32 match ip6 sport 53 0xffff "
+                        "flowid 1:1 action mirred egress redirect dev ifb-dns");
+       qosify_run_cmd(buf, false);
+
+       if (!iface->config.ingress)
+               return 0;
 
        snprintf(buf, sizeof(buf), "ip link add '%s' type ifb", ifbdev);
-       run_cmd(buf, false);
+       qosify_run_cmd(buf, false);
 
        cmd_add_qdisc(iface, ifbdev, false, eth);
 
        snprintf(buf, sizeof(buf), "ip link set dev '%s' up", ifbdev);
-       run_cmd(buf, false);
+       qosify_run_cmd(buf, false);
 
        ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " parent ffff:");
        APPEND(buf, ofs, " protocol all prio 10 u32 match u32 0 0 "
                         "flowid 1:1 action mirred egress redirect dev '%s'", ifbdev);
-       return run_cmd(buf, false);
+       return qosify_run_cmd(buf, false);
 }
 
 static void
@@ -367,8 +323,7 @@ interface_start(struct qosify_iface *iface)
 
        if (iface->config.egress)
                cmd_add_qdisc(iface, iface->ifname, true, eth);
-       if (iface->config.ingress)
-               cmd_add_ingress(iface, eth);
+       cmd_add_ingress(iface, eth);
 
        iface->active = true;
 }
@@ -518,27 +473,34 @@ void qosify_iface_check(void)
        uloop_timeout_set(&timer, 10);
 }
 
+static void
+__qosify_iface_status(struct blob_buf *b, struct qosify_iface *iface)
+{
+       void *c;
+
+       c = blobmsg_open_table(b, qosify_iface_name(iface));
+       blobmsg_add_u8(b, "active", iface->active);
+       if (iface->ifname)
+               blobmsg_add_string(b, "ifname", iface->ifname);
+       blobmsg_add_u8(b, "egress", iface->config.egress);
+       blobmsg_add_u8(b, "ingress", iface->config.ingress);
+       blobmsg_close_table(b, c);
+
+}
+
 void qosify_iface_status(struct blob_buf *b)
 {
        struct qosify_iface *iface;
-       void *c, *i;
+       void *c;
 
        c = blobmsg_open_table(b, "devices");
-       vlist_for_each_element(&devices, iface, node) {
-               i = blobmsg_open_table(b, qosify_iface_name(iface));
-               blobmsg_add_u8(b, "active", iface->active);
-               blobmsg_close_table(b, i);
-       }
+       vlist_for_each_element(&devices, iface, node)
+               __qosify_iface_status(b, iface);
        blobmsg_close_table(b, c);
 
        c = blobmsg_open_table(b, "interfaces");
-       vlist_for_each_element(&interfaces, iface, node) {
-               i = blobmsg_open_table(b, qosify_iface_name(iface));
-               blobmsg_add_u8(b, "active", iface->active);
-               if (iface->ifname)
-                       blobmsg_add_string(b, "ifname", iface->ifname);
-               blobmsg_close_table(b, i);
-       }
+       vlist_for_each_element(&interfaces, iface, node)
+               __qosify_iface_status(b, iface);
        blobmsg_close_table(b, c);
 }