summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-09-04 14:33:31 +0200
committerFelix Fietkau <nbd@openwrt.org>2011-09-04 14:33:31 +0200
commitdca8c7133b1db463f6ae71ccc6d34cd12735daef (patch)
tree320d30e5213288f9cca0946153f2f17ddfcf163b
parent07a47add60b567f65dd2051fe45ac49e1ae97524 (diff)
downloadnetifd-dca8c7133b1db463f6ae71ccc6d34cd12735daef.tar.gz
trigger proto attach from config.c
-rw-r--r--config.c9
-rw-r--r--interface.c14
-rw-r--r--interface.h3
-rw-r--r--proto-static.c2
-rw-r--r--proto.c63
-rw-r--r--proto.h6
6 files changed, 57 insertions, 40 deletions
diff --git a/config.c b/config.c
index 7ba6875..2e00364 100644
--- a/config.c
+++ b/config.c
@@ -4,6 +4,7 @@
#include "netifd.h"
#include "interface.h"
+#include "proto.h"
struct uci_context *uci_ctx;
static struct uci_package *uci_network;
@@ -140,7 +141,9 @@ config_parse_bridge_interface(struct uci_section *s)
static void
config_parse_interface(struct uci_section *s)
{
+ struct interface *iface;
const char *type;
+
DPRINTF("Create interface '%s'\n", s->e.name);
blob_buf_init(&b, 0);
@@ -151,7 +154,11 @@ config_parse_interface(struct uci_section *s)
return;
uci_to_blob(&b, s, &interface_attr_list);
- interface_alloc(s->e.name, s, b.head);
+ iface = interface_alloc(s->e.name, b.head);
+ if (!iface)
+ return;
+
+ proto_init_interface(iface, s);
}
void
diff --git a/interface.c b/interface.c
index 20956be..f08fee0 100644
--- a/interface.c
+++ b/interface.c
@@ -201,12 +201,13 @@ void interface_set_proto_state(struct interface *iface, struct interface_proto_s
}
struct interface *
-interface_alloc(const char *name, struct uci_section *s, struct blob_attr *attr)
+interface_alloc(const char *name, struct blob_attr *attr)
{
struct interface *iface;
struct blob_attr *tb[IFACE_ATTR_MAX];
struct blob_attr *cur;
struct device *dev;
+ const char *proto_name = NULL;
iface = interface_get(name);
if (iface)
@@ -221,19 +222,22 @@ interface_alloc(const char *name, struct uci_section *s, struct blob_attr *attr)
INIT_LIST_HEAD(&iface->address);
INIT_LIST_HEAD(&iface->routes);
- proto_attach_interface(iface, s);
-
- netifd_ubus_add_interface(iface);
-
blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb,
blob_data(attr), blob_len(attr));
+ if ((cur = tb[IFACE_ATTR_PROTO]))
+ proto_name = blobmsg_data(cur);
+
+ proto_attach_interface(iface, proto_name);
+
if ((cur = tb[IFACE_ATTR_IFNAME])) {
dev = device_get(blobmsg_data(cur), true);
if (dev)
device_add_user(&iface->main_dev, dev);
}
+ netifd_ubus_add_interface(iface);
+
return iface;
}
diff --git a/interface.h b/interface.h
index 9090164..f66b5b9 100644
--- a/interface.h
+++ b/interface.h
@@ -47,6 +47,7 @@ struct interface {
struct device_user *l3_iface;
/* primary protocol state */
+ const struct proto_handler *proto_handler;
struct interface_proto_state *proto;
struct list_head address, routes;
@@ -60,7 +61,7 @@ struct interface {
extern const struct config_param_list interface_attr_list;
struct interface *interface_get(const char *name);
-struct interface *interface_alloc(const char *name, struct uci_section *s, struct blob_attr *attr);
+struct interface *interface_alloc(const char *name, struct blob_attr *attr);
void interface_free(struct interface *iface);
void interface_set_proto_state(struct interface *iface, struct interface_proto_state *state);
diff --git a/proto-static.c b/proto-static.c
index 3c251f4..6b4cc23 100644
--- a/proto-static.c
+++ b/proto-static.c
@@ -215,7 +215,7 @@ static_free(struct interface_proto_state *proto)
}
struct interface_proto_state *
-static_attach(struct proto_handler *h, struct interface *iface,
+static_attach(const struct proto_handler *h, struct interface *iface,
struct uci_section *s)
{
struct static_proto_state *state;
diff --git a/proto.c b/proto.c
index 5126107..7242e80 100644
--- a/proto.c
+++ b/proto.c
@@ -41,22 +41,33 @@ no_proto_handler(struct interface_proto_state *proto,
}
static struct interface_proto_state *
-get_default_proto(void)
+default_proto_attach(const struct proto_handler *h,
+ struct interface *iface,
+ struct uci_section *s)
{
struct interface_proto_state *proto;
proto = calloc(1, sizeof(*proto));
proto->free = default_proto_free;
proto->flags = PROTO_FLAG_IMMEDIATE;
+ proto->handler = no_proto_handler;
return proto;
}
-struct proto_handler *
+static const struct proto_handler no_proto = {
+ .name = "none",
+ .attach = default_proto_attach,
+};
+
+static const struct proto_handler *
get_proto_handler(const char *name)
{
struct proto_handler *proto;
+ if (!strcmp(name, "none"))
+ return &no_proto;
+
if (!handlers.comp)
return NULL;
@@ -64,44 +75,38 @@ get_proto_handler(const char *name)
}
void
-proto_attach_interface(struct interface *iface, struct uci_section *s)
+proto_init_interface(struct interface *iface, struct uci_section *s)
{
+ const struct proto_handler *proto = iface->proto_handler;
struct interface_proto_state *state = NULL;
- struct proto_handler *proto = NULL;
- const char *proto_name;
- const char *error = NULL;
- proto_name = uci_lookup_option_string(uci_ctx, s, "proto");
- if (!proto_name) {
- error = "NO_PROTO";
- goto error;
- }
+ if (proto)
+ state = proto->attach(proto, iface, s);
- if (!strcmp(proto_name, "none")) {
- state = get_default_proto();
- state->handler = no_proto_handler;
- goto out;
+ if (!state) {
+ state = no_proto.attach(&no_proto, iface, s);
+ state->handler = invalid_proto_handler;
}
- proto = get_proto_handler(proto_name);
- if (!proto) {
- error = "INVALID_PROTO";
- goto error;
- }
+ interface_set_proto_state(iface, state);
+}
- state = proto->attach(proto, iface, s);
+void
+proto_attach_interface(struct interface *iface, const char *proto_name)
+{
+ const struct proto_handler *proto = NULL;
-error:
- if (error) {
- interface_add_error(iface, "proto", error, NULL, 0);
- state = get_default_proto();
- state->handler = invalid_proto_handler;
+ if (!proto_name) {
+ interface_add_error(iface, "proto", "NO_PROTO", NULL, 0);
+ return;
}
-out:
- interface_set_proto_state(iface, state);
-}
+ proto = get_proto_handler(proto_name);
+ if (!proto)
+ interface_add_error(iface, "proto", "INVALID_PROTO", NULL, 0);
+ iface->proto_handler = proto;
+}
int
interface_proto_event(struct interface_proto_state *proto,
diff --git a/proto.h b/proto.h
index fd9a0f8..332745c 100644
--- a/proto.h
+++ b/proto.h
@@ -32,7 +32,7 @@ struct interface_proto_state {
};
typedef struct interface_proto_state *
- (*proto_attach_cb)(struct proto_handler *h, struct interface *,
+ (*proto_attach_cb)(const struct proto_handler *h, struct interface *,
struct uci_section *s);
struct proto_handler {
@@ -43,8 +43,8 @@ struct proto_handler {
};
void add_proto_handler(struct proto_handler *p);
-struct proto_handler *get_proto_handler(const char *name);
-void proto_attach_interface(struct interface *iface, struct uci_section *s);
+void proto_init_interface(struct interface *iface, struct uci_section *s);
+void proto_attach_interface(struct interface *iface, const char *proto_name);
int interface_proto_event(struct interface_proto_state *proto,
enum interface_proto_cmd cmd, bool force);