summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-03-15 00:09:43 +0100
committerFelix Fietkau <nbd@openwrt.org>2012-03-15 00:09:43 +0100
commit1c7bff698eb7adbe239ccf400345cfda3d466f39 (patch)
tree2681de6830f3098c80a77779f5d51d70e6d8cc1f
parent87648299f8944a3268210e0315f6b5244d42fa4f (diff)
parse tunnel devices from config
-rw-r--r--CMakeLists.txt2
-rw-r--r--config.c13
-rw-r--r--device.h1
-rw-r--r--tunnel.c66
4 files changed, 77 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2062d3b..7a97aa6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,7 @@ IF(APPLE)
ENDIF()
SET(SOURCES
- main.c utils.c system.c
+ main.c utils.c system.c tunnel.c
interface.c interface-ip.c interface-event.c
proto.c proto-static.c proto-shell.c
config.c device.c bridge.c vlan.c ubus.c)
diff --git a/config.c b/config.c
index ba97a5c..d134a90 100644
--- a/config.c
+++ b/config.c
@@ -215,7 +215,7 @@ config_init_devices(void)
uci_foreach_element(&uci_network->sections, e) {
struct uci_section *s = uci_to_section(e);
- const struct device_type *devtype;
+ const struct device_type *devtype = NULL;
const char *type, *name;
if (strcmp(s->type, "device") != 0)
@@ -226,9 +226,14 @@ config_init_devices(void)
continue;
type = uci_lookup_option_string(uci_ctx, s, "type");
- if (type && !strcmp(type, "bridge"))
- devtype = &bridge_device_type;
- else
+ if (type) {
+ if (!strcmp(type, "bridge"))
+ devtype = &bridge_device_type;
+ else if (!strcmp(type, "tunnel"))
+ devtype = &tunnel_device_type;
+ }
+
+ if (!devtype)
devtype = &simple_device_type;
blob_buf_init(&b, 0);
diff --git a/device.h b/device.h
index 17676b8..7454d54 100644
--- a/device.h
+++ b/device.h
@@ -126,6 +126,7 @@ struct device_hotplug_ops {
extern const struct config_param_list device_attr_list;
extern const struct device_type simple_device_type;
extern const struct device_type bridge_device_type;
+extern const struct device_type tunnel_device_type;
void device_lock(void);
void device_unlock(void);
diff --git a/tunnel.c b/tunnel.c
new file mode 100644
index 0000000..e756973
--- /dev/null
+++ b/tunnel.c
@@ -0,0 +1,66 @@
+#include "netifd.h"
+#include "device.h"
+#include "config.h"
+#include "system.h"
+
+struct tunnel {
+ struct device dev;
+ device_state_cb set_state;
+ struct blob_attr *config;
+};
+
+static int
+tunnel_set_state(struct device *dev, bool up)
+{
+ struct tunnel *tun = container_of(dev, struct tunnel, dev);
+ int ret;
+
+ if (up) {
+ ret = system_add_ip_tunnel(dev->ifname, tun->config);
+ if (ret != 0) {
+ perror("add_ip_tunnel");
+ return ret;
+ }
+ }
+
+ ret = tun->set_state(dev, up);
+ if (ret || !up)
+ system_del_ip_tunnel(dev->ifname);
+
+ return ret;
+}
+
+static struct device *
+tunnel_create(const char *name, struct blob_attr *attr)
+{
+ struct tunnel *tun;
+ struct device *dev;
+
+ tun = calloc(1, sizeof(*tun));
+ dev = &tun->dev;
+ tun->config = config_memdup(attr);
+ device_init(dev, &tunnel_device_type, name);
+ tun->set_state = dev->set_state;
+ dev->set_state = tunnel_set_state;
+ device_set_present(dev, true);
+
+ return dev;
+}
+
+static void
+tunnel_free(struct device *dev)
+{
+ struct tunnel *tun = container_of(dev, struct tunnel, dev);
+
+ free(tun);
+}
+
+const struct device_type tunnel_device_type = {
+ .name = "IP tunnel",
+ .config_params = &tunnel_attr_list,
+
+ .create = tunnel_create,
+ .free = tunnel_free,
+};
+
+