+ blob_for_each_attr(entry, a, rem) {
+ const char *type = NULL;
+ const char *name = "ubus rule";
+ blobmsg_for_each_attr(opt, entry, orem)
+ if (!strcmp(blobmsg_name(opt), "type"))
+ type = blobmsg_get_string(opt);
+ else if (!strcmp(blobmsg_name(opt), "name"))
+ name = blobmsg_get_string(opt);
+
+ if (!type || strcmp(type, "rule"))
+ continue;
+
+ if (!(rule = alloc_rule(state)))
+ continue;
+
+ if (!fw3_parse_blob_options(rule, fw3_rule_opts, entry, name))
+ {
+ fprintf(stderr, "%s skipped due to invalid options\n", name);
+ fw3_free_rule(rule);
+ continue;
+ }
+ }
+
+ uci_foreach_element(&p->sections, e)
+ {
+ s = uci_to_section(e);
+
+ if (strcmp(s->type, "rule"))
+ continue;
+
+ if (!(rule = alloc_rule(state)))
+ continue;
+
+ if (!fw3_parse_options(rule, fw3_rule_opts, s))
+ {
+ warn_elem(e, "skipped due to invalid options");
+ fw3_free_rule(rule);
+ continue;
+ }
+ }
+
+ list_for_each_entry_safe(rule, n, &state->rules, list)
+ {