qosify: add support for keeping stats
[project/qosify.git] / ubus.c
diff --git a/ubus.c b/ubus.c
index fb5a6b7244c2dc0e76e0befaec23ed0b158dfbfa..a72d318cf0cf1d6189f2f089d3b5c1b2267de434 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -9,8 +9,7 @@
 static struct blob_buf b;
 
 static int
-qosify_ubus_add_array(struct blob_attr *attr, struct qosify_dscp_val val,
-                     enum qosify_map_id id)
+qosify_ubus_add_array(struct blob_attr *attr, uint8_t val, enum qosify_map_id id)
 {
        struct blob_attr *cur;
        int rem;
@@ -84,7 +83,7 @@ qosify_ubus_add(struct ubus_context *ctx, struct ubus_object *obj,
        int prev_timemout = qosify_map_timeout;
        struct blob_attr *tb[__CL_ADD_MAX];
        struct blob_attr *cur;
-       struct qosify_dscp_val dscp = { 0xff, 0xff };
+       uint8_t dscp = 0xff;
        int ret;
 
        blobmsg_parse(qosify_add_policy, __CL_ADD_MAX, tb,
@@ -130,15 +129,10 @@ enum {
        CL_CONFIG_TIMEOUT,
        CL_CONFIG_DSCP_UDP,
        CL_CONFIG_DSCP_TCP,
-       CL_CONFIG_DSCP_PRIO,
-       CL_CONFIG_DSCP_BULK,
        CL_CONFIG_DSCP_ICMP,
-       CL_CONFIG_BULK_TIMEOUT,
-       CL_CONFIG_BULK_PPS,
-       CL_CONFIG_PRIO_PKT_LEN,
        CL_CONFIG_INTERFACES,
        CL_CONFIG_DEVICES,
-       CL_CONFIG_ALIASES,
+       CL_CONFIG_CLASSES,
        __CL_CONFIG_MAX
 };
 
@@ -148,33 +142,12 @@ static const struct blobmsg_policy qosify_config_policy[__CL_CONFIG_MAX] = {
        [CL_CONFIG_TIMEOUT] = { "timeout", BLOBMSG_TYPE_INT32 },
        [CL_CONFIG_DSCP_UDP] = { "dscp_default_udp", BLOBMSG_TYPE_STRING },
        [CL_CONFIG_DSCP_TCP] = { "dscp_default_tcp", BLOBMSG_TYPE_STRING },
-       [CL_CONFIG_DSCP_PRIO] = { "dscp_prio", BLOBMSG_TYPE_STRING },
-       [CL_CONFIG_DSCP_BULK] = { "dscp_bulk", BLOBMSG_TYPE_STRING },
        [CL_CONFIG_DSCP_ICMP] = { "dscp_icmp", BLOBMSG_TYPE_STRING },
-       [CL_CONFIG_BULK_TIMEOUT] = { "bulk_trigger_timeout", BLOBMSG_TYPE_INT32 },
-       [CL_CONFIG_BULK_PPS] = { "bulk_trigger_pps", BLOBMSG_TYPE_INT32 },
-       [CL_CONFIG_PRIO_PKT_LEN] = { "prio_max_avg_pkt_len", BLOBMSG_TYPE_INT32 },
        [CL_CONFIG_INTERFACES] = { "interfaces", BLOBMSG_TYPE_TABLE },
        [CL_CONFIG_DEVICES] = { "devices", BLOBMSG_TYPE_TABLE },
-       [CL_CONFIG_ALIASES] = { "aliases", BLOBMSG_TYPE_TABLE },
+       [CL_CONFIG_CLASSES] = { "classes", BLOBMSG_TYPE_TABLE },
 };
 
-static int __set_dscp(struct qosify_dscp_val *dest, struct blob_attr *attr, bool reset)
-{
-       if (reset) {
-                dest->ingress = 0xff;
-                dest->egress = 0xff;
-       }
-
-       if (!attr)
-               return 0;
-
-       if (qosify_map_dscp_value(blobmsg_get_string(attr), dest))
-               return -1;
-
-       return 0;
-}
-
 static int
 qosify_ubus_config(struct ubus_context *ctx, struct ubus_object *obj,
                   struct ubus_request_data *req, const char *method,
@@ -182,7 +155,7 @@ qosify_ubus_config(struct ubus_context *ctx, struct ubus_object *obj,
 {
        struct blob_attr *tb[__CL_CONFIG_MAX];
        struct blob_attr *cur;
-       struct qosify_dscp_val dscp;
+       uint8_t dscp;
        bool reset = false;
        int ret;
 
@@ -195,8 +168,8 @@ qosify_ubus_config(struct ubus_context *ctx, struct ubus_object *obj,
        if (reset)
                qosify_map_reset_config();
 
-       if ((cur = tb[CL_CONFIG_ALIASES]) != NULL || reset)
-               qosify_map_set_aliases(cur);
+       if ((cur = tb[CL_CONFIG_CLASSES]) != NULL || reset)
+               qosify_map_set_classes(cur);
 
        if ((cur = tb[CL_CONFIG_TIMEOUT]) != NULL)
                qosify_map_timeout = blobmsg_get_u32(cur);
@@ -205,27 +178,17 @@ qosify_ubus_config(struct ubus_context *ctx, struct ubus_object *obj,
            (ret = qosify_ubus_set_files(cur) != 0))
                return ret;
 
-       __set_dscp(&dscp, tb[CL_CONFIG_DSCP_UDP], true);
-       if (dscp.ingress != 0xff)
-               qosify_map_set_dscp_default(CL_MAP_UDP_PORTS, dscp);
-
-       __set_dscp(&dscp, tb[CL_CONFIG_DSCP_TCP], true);
-       if (dscp.ingress != 0xff)
-               qosify_map_set_dscp_default(CL_MAP_TCP_PORTS, dscp);
-
-       if (__set_dscp(&config.dscp_prio, tb[CL_CONFIG_DSCP_PRIO], reset) ||
-           __set_dscp(&config.dscp_bulk, tb[CL_CONFIG_DSCP_BULK], reset) ||
-           __set_dscp(&config.dscp_icmp, tb[CL_CONFIG_DSCP_ICMP], reset))
+       if (map_parse_flow_config(&flow_config, msg, reset) ||
+           map_fill_dscp_value(&config.dscp_icmp, tb[CL_CONFIG_DSCP_ICMP], reset))
                return UBUS_STATUS_INVALID_ARGUMENT;
 
-       if ((cur = tb[CL_CONFIG_BULK_TIMEOUT]) != NULL)
-               config.bulk_trigger_timeout = blobmsg_get_u32(cur);
-
-       if ((cur = tb[CL_CONFIG_BULK_PPS]) != NULL)
-               config.bulk_trigger_pps = blobmsg_get_u32(cur);
+       map_fill_dscp_value(&dscp, tb[CL_CONFIG_DSCP_UDP], true);
+       if (dscp != 0xff)
+               qosify_map_set_dscp_default(CL_MAP_UDP_PORTS, dscp);
 
-       if ((cur = tb[CL_CONFIG_PRIO_PKT_LEN]) != NULL)
-               config.prio_max_avg_pkt_len = blobmsg_get_u32(cur);
+       map_fill_dscp_value(&dscp, tb[CL_CONFIG_DSCP_TCP], true);
+       if (dscp != 0xff)
+               qosify_map_set_dscp_default(CL_MAP_TCP_PORTS, dscp);
 
        qosify_map_update_config();
 
@@ -263,6 +226,28 @@ qosify_ubus_status(struct ubus_context *ctx, struct ubus_object *obj,
        return 0;
 }
 
+static int
+qosify_ubus_get_stats(struct ubus_context *ctx, struct ubus_object *obj,
+                     struct ubus_request_data *req, const char *method,
+                     struct blob_attr *msg)
+{
+       static const struct blobmsg_policy policy =
+               { "reset", BLOBMSG_TYPE_BOOL };
+       struct blob_attr *tb;
+       bool reset = false;
+
+       blobmsg_parse(&policy, 1, &tb, blobmsg_data(msg), blobmsg_len(msg));
+
+       reset = tb && blobmsg_get_u8(tb);
+
+       blob_buf_init(&b, 0);
+       qosify_map_stats(&b, reset);
+       ubus_send_reply(ctx, req, b.head);
+       blob_buf_free(&b);
+
+       return 0;
+}
+
 static int
 qosify_ubus_check_devices(struct ubus_context *ctx, struct ubus_object *obj,
                          struct ubus_request_data *req, const char *method,
@@ -330,6 +315,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_NOARG("get_stats", qosify_ubus_get_stats),
        UBUS_METHOD("add_dns_host", qosify_ubus_add_dns_host, qosify_dns_policy),
        UBUS_METHOD_NOARG("check_devices", qosify_ubus_check_devices),
 };
@@ -344,22 +330,11 @@ static struct ubus_object qosify_object = {
        .n_methods = ARRAY_SIZE(qosify_methods),
 };
 
-static int
-qosify_dnsmasq_cb(struct ubus_context *ctx, struct ubus_object *obj,
-                 struct ubus_request_data *req, const char *method,
-                 struct blob_attr *msg)
-{
-       if (!strcmp(method, "dns_result"))
-               __qosify_ubus_add_dns_host(msg);
-
-       return 0;
-}
-
 static void
 qosify_subscribe_dnsmasq(struct ubus_context *ctx)
 {
        static struct ubus_subscriber sub = {
-               .cb = qosify_dnsmasq_cb,
+               .cb = qosify_ubus_add_dns_host,
        };
        uint32_t id;
 
@@ -390,6 +365,8 @@ qosify_ubus_event_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
        path = blobmsg_get_string(attr);
        if (!strcmp(path, "dnsmasq.dns"))
                qosify_subscribe_dnsmasq(ctx);
+       else if (!strcmp(path, "bridger"))
+               qosify_ubus_update_bridger(false);
 }
 
 
@@ -407,6 +384,25 @@ ubus_connect_handler(struct ubus_context *ctx)
 
 static struct ubus_auto_conn conn;
 
+void qosify_ubus_update_bridger(bool shutdown)
+{
+       struct ubus_request req;
+       uint32_t id;
+       void *c;
+
+       if (ubus_lookup_id(&conn.ctx, "bridger", &id))
+               return;
+
+       blob_buf_init(&b, 0);
+       blobmsg_add_string(&b, "name", "qosify");
+       c = blobmsg_open_array(&b, "devices");
+       if (!shutdown)
+               qosify_iface_get_devices(&b);
+       blobmsg_close_array(&b, c);
+
+       ubus_invoke_async(&conn.ctx, id, "set_blacklist", b.head, &req);
+}
+
 int qosify_ubus_init(void)
 {
        conn.cb = ubus_connect_handler;
@@ -417,6 +413,7 @@ int qosify_ubus_init(void)
 
 void qosify_ubus_stop(void)
 {
+       qosify_ubus_update_bridger(true);
        ubus_auto_shutdown(&conn);
 }
 
@@ -467,6 +464,7 @@ int qosify_ubus_check_interface(const char *name, char *ifname, int ifname_len)
        if (ubus_lookup_id(&conn.ctx, obj_name, &id))
                return -1;
 
+       blob_buf_init(&b, 0);
        ubus_invoke(&conn.ctx, id, "status", b.head, netifd_if_cb, &req, 1000);
 
        if (!ifname[0])