parse tunnel devices from config
authorFelix Fietkau <nbd@openwrt.org>
Wed, 14 Mar 2012 23:09:43 +0000 (00:09 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 14 Mar 2012 23:09:43 +0000 (00:09 +0100)
CMakeLists.txt
config.c
device.h
tunnel.c [new file with mode: 0644]

index 2062d3b..7a97aa6 100644 (file)
@@ -11,7 +11,7 @@ IF(APPLE)
 ENDIF()
 
 SET(SOURCES
 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)
        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)
index ba97a5c..d134a90 100644 (file)
--- 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);
 
        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)
                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");
                        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);
                        devtype = &simple_device_type;
 
                blob_buf_init(&b, 0);
index 17676b8..7454d54 100644 (file)
--- 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 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);
 
 void device_lock(void);
 void device_unlock(void);
diff --git a/tunnel.c b/tunnel.c
new file mode 100644 (file)
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,
+};
+
+