+static void
+bridge_config_init(struct device *dev)
+{
+ struct bridge_state *bst;
+ struct blob_attr *cur;
+ int rem;
+
+ bst = container_of(dev, struct bridge_state, dev);
+
+ if (bst->config.bridge_empty) {
+ bst->force_active = true;
+ device_set_present(&bst->dev, true);
+ }
+
+ vlist_update(&bst->members);
+ if (bst->ifnames) {
+ blobmsg_for_each_attr(cur, bst->ifnames, rem) {
+ bridge_add_member(bst, blobmsg_data(cur));
+ }
+ }
+ vlist_flush(&bst->members);
+}
+
+static void
+bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
+{
+ struct bridge_config *cfg = &bst->config;
+ struct blob_attr *cur;
+
+ /* defaults */
+ cfg->stp = false;
+ cfg->forward_delay = 2;
+ cfg->igmp_snoop = false;
+ cfg->bridge_empty = false;
+ cfg->priority = 0x7FFF;
+
+ if ((cur = tb[BRIDGE_ATTR_STP]))
+ cfg->stp = blobmsg_get_bool(cur);
+
+ if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY]))
+ cfg->forward_delay = blobmsg_get_u32(cur);
+
+ if ((cur = tb[BRIDGE_ATTR_PRIORITY]))
+ cfg->priority = blobmsg_get_u32(cur);
+
+ if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP]))
+ cfg->igmp_snoop = blobmsg_get_bool(cur);
+
+ if ((cur = tb[BRIDGE_ATTR_AGEING_TIME])) {
+ cfg->ageing_time = blobmsg_get_u32(cur);
+ cfg->flags |= BRIDGE_OPT_AGEING_TIME;
+ }
+
+ if ((cur = tb[BRIDGE_ATTR_HELLO_TIME])) {
+ cfg->hello_time = blobmsg_get_u32(cur);
+ cfg->flags |= BRIDGE_OPT_HELLO_TIME;
+ }
+
+ if ((cur = tb[BRIDGE_ATTR_MAX_AGE])) {
+ cfg->max_age = blobmsg_get_u32(cur);
+ cfg->flags |= BRIDGE_OPT_MAX_AGE;
+ }
+
+ if ((cur = tb[BRIDGE_ATTR_BRIDGE_EMPTY]))
+ cfg->bridge_empty = blobmsg_get_bool(cur);
+}
+
+enum dev_change_type
+bridge_reload(struct device *dev, struct blob_attr *attr)