ubus: use blobmsg_parse to validate device attributes and decouple the found device...
authorFelix Fietkau <nbd@openwrt.org>
Mon, 30 Jun 2014 17:25:25 +0000 (19:25 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 30 Jun 2014 18:52:22 +0000 (20:52 +0200)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
ubus.c

diff --git a/ubus.c b/ubus.c
index a5f3a65a9d7c5b8ebe175ea32a77d481c9712abb..877104ad29aeb2cafa454a9532b95c05d1036296 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -111,11 +111,21 @@ parse_subnets(struct list_head *head, enum fw3_family family,
 struct fw3_device *
 fw3_ubus_device(const char *net)
 {
+       enum {
+               DEV_INTERFACE,
+               DEV_DEVICE,
+               DEV_L3_DEVICE,
+               __DEV_MAX
+       };
+       static const struct blobmsg_policy policy[__DEV_MAX] = {
+               [DEV_INTERFACE] = { "interface", BLOBMSG_TYPE_STRING },
+               [DEV_DEVICE] = { "device", BLOBMSG_TYPE_STRING },
+               [DEV_L3_DEVICE] = { "l3_device", BLOBMSG_TYPE_STRING },
+       };
        struct fw3_device *dev = NULL;
-       struct blob_attr *c, *cur;
-       unsigned r, rem;
-       char *data;
-       bool matched;
+       struct blob_attr *tb[__DEV_MAX];
+       struct blob_attr *cur;
+       int rem;
 
        if (!net || !interfaces)
                return NULL;
@@ -124,24 +134,22 @@ fw3_ubus_device(const char *net)
        if (!dev)
                return NULL;
 
-       blobmsg_for_each_attr(c, interfaces, r) {
-               matched = false;
-               blobmsg_for_each_attr(cur, c, rem)
-                       if (!strcmp(blobmsg_name(cur), "interface"))
-                               matched = !strcmp(blobmsg_get_string(cur), net);
+       blobmsg_for_each_attr(cur, interfaces, rem) {
+               char *name;
 
-               if (!matched)
+               blobmsg_parse(policy, __DEV_MAX, tb, blobmsg_data(cur), blobmsg_len(cur));
+               if (!tb[DEV_INTERFACE] ||
+                   strcmp(blobmsg_data(tb[DEV_INTERFACE]), net) != 0)
                        continue;
 
-               blobmsg_for_each_attr(cur, c, rem) {
-                       data = blobmsg_data(cur);
-
-                       if (!strcmp(blobmsg_name(cur), "device") && !dev->name[0])
-                               snprintf(dev->name, sizeof(dev->name), "%s", data);
-                       else if (!strcmp(blobmsg_name(cur), "l3_device"))
-                               snprintf(dev->name, sizeof(dev->name), "%s", data);
-               }
+               if (tb[DEV_L3_DEVICE])
+                       name = blobmsg_data(tb[DEV_L3_DEVICE]);
+               else if (tb[DEV_DEVICE])
+                       name = blobmsg_data(tb[DEV_DEVICE]);
+               else
+                       continue;
 
+               snprintf(dev->name, sizeof(dev->name), "%s", name);
                dev->set = !!dev->name[0];
                return dev;
        }