capabilities: Some plugins don't actually require capabilities at runtime
[strongswan.git] / src / libcharon / plugins / kernel_libipsec / kernel_libipsec_plugin.c
1 /*
2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "kernel_libipsec_plugin.h"
17 #include "kernel_libipsec_ipsec.h"
18 #include "kernel_libipsec_router.h"
19
20 #include <daemon.h>
21 #include <ipsec.h>
22 #include <networking/tun_device.h>
23
24 #define TUN_DEFAULT_MTU 1400
25
26 typedef struct private_kernel_libipsec_plugin_t private_kernel_libipsec_plugin_t;
27
28 /**
29 * private data of "kernel" libipsec plugin
30 */
31 struct private_kernel_libipsec_plugin_t {
32
33 /**
34 * implements plugin interface
35 */
36 kernel_libipsec_plugin_t public;
37
38 /**
39 * TUN device created by this plugin
40 */
41 tun_device_t *tun;
42
43 /**
44 * Packet router
45 */
46 kernel_libipsec_router_t *router;
47 };
48
49 METHOD(plugin_t, get_name, char*,
50 private_kernel_libipsec_plugin_t *this)
51 {
52 return "kernel-libipsec";
53 }
54
55 /**
56 * Create the kernel_libipsec_router_t instance
57 */
58 static bool create_router(private_kernel_libipsec_plugin_t *this,
59 plugin_feature_t *feature, bool reg, void *arg)
60 {
61 if (reg)
62 { /* registers as packet handler etc. */
63 this->router = kernel_libipsec_router_create();
64 }
65 else
66 {
67 DESTROY_IF(this->router);
68 }
69 return TRUE;
70 }
71
72 METHOD(plugin_t, get_features, int,
73 private_kernel_libipsec_plugin_t *this, plugin_feature_t *features[])
74 {
75 static plugin_feature_t f[] = {
76 PLUGIN_CALLBACK(kernel_ipsec_register, kernel_libipsec_ipsec_create),
77 PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
78 PLUGIN_CALLBACK((plugin_feature_callback_t)create_router, NULL),
79 PLUGIN_PROVIDE(CUSTOM, "kernel-libipsec-router"),
80 PLUGIN_DEPENDS(CUSTOM, "libcharon-receiver"),
81 };
82 *features = f;
83 return countof(f);
84 }
85
86 METHOD(plugin_t, destroy, void,
87 private_kernel_libipsec_plugin_t *this)
88 {
89 if (this->tun)
90 {
91 lib->set(lib, "kernel-libipsec-tun", NULL);
92 this->tun->destroy(this->tun);
93 }
94 libipsec_deinit();
95 free(this);
96 }
97
98 /*
99 * see header file
100 */
101 plugin_t *kernel_libipsec_plugin_create()
102 {
103 private_kernel_libipsec_plugin_t *this;
104
105 if (!lib->caps->check(lib->caps, CAP_NET_ADMIN))
106 { /* required to create TUN devices */
107 DBG1(DBG_KNL, "kernel-libipsec plugin requires CAP_NET_ADMIN "
108 "capability");
109 return NULL;
110 }
111
112 INIT(this,
113 .public = {
114 .plugin = {
115 .get_name = _get_name,
116 .get_features = _get_features,
117 .destroy = _destroy,
118 },
119 },
120 );
121
122 if (!libipsec_init())
123 {
124 DBG1(DBG_LIB, "initialization of libipsec failed");
125 destroy(this);
126 return NULL;
127 }
128
129 this->tun = tun_device_create("ipsec%d");
130 if (!this->tun)
131 {
132 DBG1(DBG_KNL, "failed to create TUN device");
133 destroy(this);
134 return NULL;
135 }
136 if (!this->tun->set_mtu(this->tun, TUN_DEFAULT_MTU) ||
137 !this->tun->up(this->tun))
138 {
139 DBG1(DBG_KNL, "failed to configure TUN device");
140 destroy(this);
141 return NULL;
142 }
143 lib->set(lib, "kernel-libipsec-tun", this->tun);
144
145 /* set TUN device as default to install VIPs */
146 lib->settings->set_str(lib->settings, "%s.install_virtual_ip_on",
147 this->tun->get_name(this->tun), charon->name);
148 return &this->public.plugin;
149 }