+ enum {
+ ADDR_INTERFACE,
+ ADDR_IPV4,
+ ADDR_IPV6,
+ ADDR_IPV6_PREFIX,
+ __ADDR_MAX
+ };
+ static const struct blobmsg_policy policy[__ADDR_MAX] = {
+ [ADDR_INTERFACE] = { "interface", BLOBMSG_TYPE_STRING },
+ [ADDR_IPV4] = { "ipv4-address", BLOBMSG_TYPE_ARRAY },
+ [ADDR_IPV6] = { "ipv6-address", BLOBMSG_TYPE_ARRAY },
+ [ADDR_IPV6_PREFIX] = { "ipv6-prefix-assignment", BLOBMSG_TYPE_ARRAY },
+ };
+ struct blob_attr *tb[__ADDR_MAX];
+ struct blob_attr *cur;
+ int rem;
+
+ if (!net || !interfaces)
+ return;
+
+ blobmsg_for_each_attr(cur, interfaces, rem) {
+ blobmsg_parse(policy, __ADDR_MAX, tb, blobmsg_data(cur), blobmsg_len(cur));
+
+ if (!tb[ADDR_INTERFACE] ||
+ strcmp(blobmsg_data(tb[ADDR_INTERFACE]), net) != 0)
+ continue;
+
+ parse_subnets(list, FW3_FAMILY_V4, blobmsg_data(tb[ADDR_IPV4]), blobmsg_data_len(tb[ADDR_IPV4]));
+ parse_subnets(list, FW3_FAMILY_V6, blobmsg_data(tb[ADDR_IPV6]), blobmsg_data_len(tb[ADDR_IPV6]));
+ parse_subnets(list, FW3_FAMILY_V6, blobmsg_data(tb[ADDR_IPV6_PREFIX]), blobmsg_data_len(tb[ADDR_IPV6_PREFIX]));
+ }