2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
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>.
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
16 #include "kernel_libipsec_plugin.h"
17 #include "kernel_libipsec_ipsec.h"
21 #include <networking/tun_device.h>
22 #include <processing/jobs/callback_job.h>
23 #include <utils/debug.h>
25 #define TUN_DEFAULT_MTU 1400
27 typedef struct private_kernel_libipsec_plugin_t private_kernel_libipsec_plugin_t
;
30 * private data of "kernel" libipsec plugin
32 struct private_kernel_libipsec_plugin_t
{
35 * implements plugin interface
37 kernel_libipsec_plugin_t
public;
40 * TUN device created by this plugin
46 METHOD(plugin_t
, get_name
, char*,
47 private_kernel_libipsec_plugin_t
*this)
49 return "kernel-libipsec";
55 static void send_esp(void *data
, esp_packet_t
*packet
)
57 charon
->sender
->send_no_marker(charon
->sender
, (packet_t
*)packet
);
63 static void deliver_plain(private_kernel_libipsec_plugin_t
*this,
66 this->tun
->write_packet(this->tun
, packet
->get_encoding(packet
));
67 packet
->destroy(packet
);
73 static void receiver_esp_cb(void *data
, packet_t
*packet
)
75 ipsec
->processor
->queue_inbound(ipsec
->processor
,
76 esp_packet_create_from_packet(packet
));
80 * Job handling outbound plaintext packets
82 static job_requeue_t
handle_plain(private_kernel_libipsec_plugin_t
*this)
86 if (this->tun
->read_packet(this->tun
, &raw
))
90 packet
= ip_packet_create(raw
);
93 ipsec
->processor
->queue_outbound(ipsec
->processor
, packet
);
97 DBG1(DBG_KNL
, "invalid IP packet read from TUN device");
100 return JOB_REQUEUE_DIRECT
;
104 * Initialize/deinitialize sender and receiver
106 static bool packet_handler_cb(private_kernel_libipsec_plugin_t
*this,
107 plugin_feature_t
*feature
, bool reg
, void *arg
)
111 ipsec
->processor
->register_outbound(ipsec
->processor
, send_esp
, NULL
);
112 ipsec
->processor
->register_inbound(ipsec
->processor
,
113 (ipsec_inbound_cb_t
)deliver_plain
, this);
114 charon
->receiver
->add_esp_cb(charon
->receiver
,
115 (receiver_esp_cb_t
)receiver_esp_cb
, NULL
);
116 lib
->processor
->queue_job(lib
->processor
,
117 (job_t
*)callback_job_create((callback_job_cb_t
)handle_plain
, this,
118 NULL
, (callback_job_cancel_t
)return_false
));
122 charon
->receiver
->del_esp_cb(charon
->receiver
,
123 (receiver_esp_cb_t
)receiver_esp_cb
);
124 ipsec
->processor
->unregister_outbound(ipsec
->processor
,
125 (ipsec_outbound_cb_t
)send_esp
);
126 ipsec
->processor
->unregister_inbound(ipsec
->processor
,
127 (ipsec_inbound_cb_t
)deliver_plain
);
132 METHOD(plugin_t
, get_features
, int,
133 private_kernel_libipsec_plugin_t
*this, plugin_feature_t
*features
[])
135 static plugin_feature_t f
[] = {
136 PLUGIN_CALLBACK(kernel_ipsec_register
, kernel_libipsec_ipsec_create
),
137 PLUGIN_PROVIDE(CUSTOM
, "kernel-ipsec"),
138 PLUGIN_CALLBACK((plugin_feature_callback_t
)packet_handler_cb
, NULL
),
139 PLUGIN_PROVIDE(CUSTOM
, "kernel-libipsec-handler"),
140 PLUGIN_DEPENDS(CUSTOM
, "libcharon-receiver"),
146 METHOD(plugin_t
, destroy
, void,
147 private_kernel_libipsec_plugin_t
*this)
151 lib
->set(lib
, "kernel-libipsec-tun", NULL
);
152 this->tun
->destroy(this->tun
);
161 plugin_t
*kernel_libipsec_plugin_create()
163 private_kernel_libipsec_plugin_t
*this;
168 .get_name
= _get_name
,
169 .get_features
= _get_features
,
175 if (!libipsec_init())
177 DBG1(DBG_LIB
, "initialization of libipsec failed");
182 this->tun
= tun_device_create("ipsec%d");
185 DBG1(DBG_KNL
, "failed to create TUN device");
189 if (!this->tun
->set_mtu(this->tun
, TUN_DEFAULT_MTU
) ||
190 !this->tun
->up(this->tun
))
192 DBG1(DBG_KNL
, "failed to configure TUN device");
196 lib
->set(lib
, "kernel-libipsec-tun", this->tun
);
198 /* set TUN device as default to install VIPs */
199 lib
->settings
->set_str(lib
->settings
, "%s.install_virtual_ip_on",
200 this->tun
->get_name(this->tun
), charon
->name
);
201 return &this->public.plugin
;