diff options
Diffstat (limited to 'tunnel.c')
-rw-r--r-- | tunnel.c | 66 |
1 files changed, 66 insertions, 0 deletions
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, +}; + + |