}
struct interface *
-interface_alloc(const char *name, struct blob_attr *config)
+interface_alloc(const char *name, struct blob_attr *config, bool dynamic)
{
struct interface *iface;
struct blob_attr *tb[IFACE_ATTR_MAX];
iface->autostart = blobmsg_get_bool_default(tb[IFACE_ATTR_AUTO], true);
iface->force_link = blobmsg_get_bool_default(tb[IFACE_ATTR_FORCE_LINK], force_link);
+ iface->dynamic = dynamic;
iface->proto_ip.no_defaultroute =
!blobmsg_get_bool_default(tb[IFACE_ATTR_DEFAULTROUTE], true);
iface->proto_ip.no_dns =
return iface;
}
-void interface_set_dynamic(struct interface *iface)
-{
- iface->dynamic = true;
- iface->autostart = true;
- iface->node.version = -1; // Don't delete on reload
-}
-
static bool __interface_add(struct interface *iface, struct blob_attr *config, bool alias)
{
struct blob_attr *tb[IFACE_ATTR_MAX];
struct blob_attr *cur;
+ char *name = iface->dynamic ? strdup(iface->name) : NULL;
blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb,
blob_data(config), blob_len(config));
iface->config = config;
vlist_add(&interfaces, &iface->node, iface->name);
+
+ if (name) {
+ iface = vlist_find(&interfaces, name, iface, node);
+ free(name);
+
+ if (!iface)
+ return false;
+
+ /* Don't delete dynamic interface on reload */
+ iface->node.version = -1;
+ }
+
return true;
}
-void
+bool
interface_add(struct interface *iface, struct blob_attr *config)
{
- __interface_add(iface, config, false);
+ return __interface_add(iface, config, false);
}
bool
if_old->config_autostart = if_new->config_autostart;
if_old->ifname = if_new->ifname;
if_old->parent_ifname = if_new->parent_ifname;
+ if_old->dynamic = if_new->dynamic;
if_old->proto_handler = if_new->proto_handler;
if_old->force_link = if_new->force_link;
if_old->dns_metric = if_new->dns_metric;
extern struct vlist_tree interfaces;
extern const struct uci_blob_param_list interface_attr_list;
-struct interface *interface_alloc(const char *name, struct blob_attr *config);
+struct interface *interface_alloc(const char *name, struct blob_attr *config, bool dynamic);
-void interface_set_dynamic(struct interface *iface);
-
-void interface_add(struct interface *iface, struct blob_attr *config);
+bool interface_add(struct interface *iface, struct blob_attr *config);
bool interface_add_alias(struct interface *iface, struct blob_attr *config);
void interface_set_proto_state(struct interface *iface, struct interface_proto_state *state);
const char *name = blobmsg_get_string(tb[DI_NAME]);
- iface = interface_alloc(name, msg);
+ iface = interface_alloc(name, msg, true);
if (!iface)
return UBUS_STATUS_UNKNOWN_ERROR;
config = blob_memdup(msg);
if (!config)
- goto error;
-
- interface_add(iface, config);
-
- // need to look up the interface name again, in case of config update
- // the pointer will have changed
- iface = vlist_find(&interfaces, name, iface, node);
- if (!iface)
- return UBUS_STATUS_UNKNOWN_ERROR;
+ goto error_free;
- // Set interface as dynamic
- interface_set_dynamic(iface);
+ if (!interface_add(iface, config))
+ goto error;
return UBUS_STATUS_OK;
-error:
+error_free:
free(iface);
+error:
return UBUS_STATUS_UNKNOWN_ERROR;
}