do not use a route if outgoing interface is down
[strongswan.git] / src / charon / kernel / kernel_interface.c
1 /*
2 * Copyright (C) 2008 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 * $Id$
16 */
17
18 #include "kernel_interface.h"
19
20 #include <pthread.h>
21
22 #include <daemon.h>
23 #include <utils/linked_list.h>
24 #include <utils/mutex.h>
25
26 typedef struct private_kernel_interface_t private_kernel_interface_t;
27
28 /**
29 * Private data of a kernel_interface_t object.
30 */
31 struct private_kernel_interface_t {
32
33 /**
34 * Public part of kernel_interface_t object.
35 */
36 kernel_interface_t public;
37
38 /**
39 * list of registered ipsec kernel interfaces
40 */
41 linked_list_t *ipsec_interfaces;
42
43 /**
44 * list of registered network kernel interfaces
45 */
46 linked_list_t *net_interfaces;
47
48 /**
49 * ipsec interface
50 */
51 kernel_ipsec_t *ipsec;
52
53 /**
54 * network interface
55 */
56 kernel_net_t *net;
57
58 /**
59 * locking mutex
60 */
61 mutex_t *mutex;
62 };
63
64 /**
65 * Implementation of kernel_interface_t.get_spi
66 */
67 static status_t get_spi(private_kernel_interface_t *this, host_t *src, host_t *dst,
68 protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
69 {
70 return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi);
71 }
72
73 /**
74 * Implementation of kernel_interface_t.get_cpi
75 */
76 static status_t get_cpi(private_kernel_interface_t *this, host_t *src, host_t *dst,
77 u_int32_t reqid, u_int16_t *cpi)
78 {
79 return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi);
80 }
81
82 /**
83 * Implementation of kernel_interface_t.add_sa
84 */
85 static status_t add_sa(private_kernel_interface_t *this, host_t *src, host_t *dst,
86 u_int32_t spi, protocol_id_t protocol, u_int32_t reqid,
87 u_int64_t expire_soft, u_int64_t expire_hard,
88 u_int16_t enc_alg, chunk_t enc_key,
89 u_int16_t int_alg, chunk_t int_key,
90 ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool encap,
91 bool inbound)
92 {
93 return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
94 expire_soft, expire_hard, enc_alg, enc_key, int_alg, int_key,
95 mode, ipcomp, cpi, encap, inbound);
96 }
97
98 /**
99 * Implementation of kernel_interface_t.update_sa
100 */
101 static status_t update_sa(private_kernel_interface_t *this, u_int32_t spi,
102 protocol_id_t protocol, u_int16_t cpi, host_t *src, host_t *dst,
103 host_t *new_src, host_t *new_dst, bool encap, bool new_encap)
104 {
105 return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst,
106 new_src, new_dst, encap, new_encap);
107 }
108
109 /**
110 * Implementation of kernel_interface_t.del_sa
111 */
112 static status_t del_sa(private_kernel_interface_t *this, host_t *dst, u_int32_t spi,
113 protocol_id_t protocol, u_int16_t cpi)
114 {
115 return this->ipsec->del_sa(this->ipsec, dst, spi, protocol, cpi);
116 }
117
118 /**
119 * Implementation of kernel_interface_t.add_policy
120 */
121 static status_t add_policy(private_kernel_interface_t *this, host_t *src, host_t *dst,
122 traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
123 policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
124 u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
125 bool routed)
126 {
127 return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts,
128 direction, spi, protocol, reqid, mode, ipcomp, cpi, routed);
129 }
130
131 /**
132 * Implementation of kernel_interface_t.query_policy
133 */
134 static status_t query_policy(private_kernel_interface_t *this,
135 traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
136 policy_dir_t direction, u_int32_t *use_time)
137 {
138 return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts, direction, use_time);
139 }
140
141 /**
142 * Implementation of kernel_interface_t.del_policy
143 */
144 static status_t del_policy(private_kernel_interface_t *this,
145 traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
146 policy_dir_t direction, bool unrouted)
147 {
148 return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts, direction, unrouted);
149 }
150
151 /**
152 * Implementation of kernel_interface_t.get_source_addr
153 */
154 static host_t *get_source_addr(private_kernel_interface_t *this,
155 host_t *dest, host_t *src)
156 {
157 return this->net->get_source_addr(this->net, dest, src);
158 }
159
160 /**
161 * Implementation of kernel_interface_t.get_nexthop
162 */
163 static host_t *get_nexthop(private_kernel_interface_t *this, host_t *dest)
164 {
165 return this->net->get_nexthop(this->net, dest);
166 }
167
168 /**
169 * Implementation of kernel_interface_t.get_interface
170 */
171 static char* get_interface(private_kernel_interface_t *this, host_t *host)
172 {
173 return this->net->get_interface(this->net, host);
174 }
175
176 /**
177 * Implementation of kernel_interface_t.create_address_enumerator
178 */
179 static enumerator_t *create_address_enumerator(private_kernel_interface_t *this,
180 bool include_down_ifaces, bool include_virtual_ips)
181 {
182 return this->net->create_address_enumerator(this->net, include_down_ifaces,
183 include_virtual_ips);
184 }
185
186 /**
187 * Implementation of kernel_interface_t.add_ip
188 */
189 static status_t add_ip(private_kernel_interface_t *this, host_t *virtual_ip,
190 host_t *iface_ip)
191 {
192 return this->net->add_ip(this->net, virtual_ip, iface_ip);
193 }
194
195 /**
196 * Implementation of kernel_interface_t.del_ip
197 */
198 static status_t del_ip(private_kernel_interface_t *this, host_t *virtual_ip)
199 {
200 return this->net->del_ip(this->net, virtual_ip);
201 }
202
203 /**
204 * Implementation of kernel_interface_t.add_route
205 */
206 static status_t add_route(private_kernel_interface_t *this, chunk_t dst_net,
207 u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
208 {
209 return this->net->add_route(this->net, dst_net, prefixlen, gateway, src_ip,
210 if_name);
211 }
212
213 /**
214 * Implementation of kernel_interface_t.del_route
215 */
216 static status_t del_route(private_kernel_interface_t *this, chunk_t dst_net,
217 u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
218 {
219 return this->net->del_route(this->net, dst_net, prefixlen, gateway, src_ip,
220 if_name);
221 }
222
223
224 /**
225 * Implementation of kernel_interface_t.get_address_by_ts
226 */
227 static status_t get_address_by_ts(private_kernel_interface_t *this,
228 traffic_selector_t *ts, host_t **ip)
229 {
230 enumerator_t *addrs;
231 host_t *host;
232 int family;
233 bool found = FALSE;
234
235 DBG2(DBG_KNL, "getting a local address in traffic selector %R", ts);
236
237 /* if we have a family which includes localhost, we do not
238 * search for an IP, we use the default */
239 family = ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6;
240
241 if (family == AF_INET)
242 {
243 host = host_create_from_string("127.0.0.1", 0);
244 }
245 else
246 {
247 host = host_create_from_string("::1", 0);
248 }
249
250 if (ts->includes(ts, host))
251 {
252 *ip = host_create_any(family);
253 host->destroy(host);
254 DBG2(DBG_KNL, "using host %H", *ip);
255 return SUCCESS;
256 }
257 host->destroy(host);
258
259 addrs = create_address_enumerator(this, TRUE, TRUE);
260 while (addrs->enumerate(addrs, (void**)&host))
261 {
262 if (ts->includes(ts, host))
263 {
264 found = TRUE;
265 *ip = host->clone(host);
266 break;
267 }
268 }
269 addrs->destroy(addrs);
270
271 if (!found)
272 {
273 DBG1(DBG_KNL, "no local address found in traffic selector %R", ts);
274 return FAILED;
275 }
276
277 DBG2(DBG_KNL, "using host %H", *ip);
278 return SUCCESS;
279 }
280
281
282 /**
283 * Implementation of kernel_interface_t.add_ipsec_interface.
284 */
285 static void add_ipsec_interface(private_kernel_interface_t *this,
286 kernel_ipsec_constructor_t *create)
287 {
288 this->mutex->lock(this->mutex);
289 this->ipsec_interfaces->insert_last(this->ipsec_interfaces, create);
290 this->mutex->unlock(this->mutex);
291 }
292
293 /**
294 * Implementation of kernel_interface_t.remove_ipsec_interface.
295 */
296 static void remove_ipsec_interface(private_kernel_interface_t *this,
297 kernel_ipsec_constructor_t *create)
298 {
299 this->mutex->lock(this->mutex);
300 this->ipsec_interfaces->remove(this->ipsec_interfaces, create, NULL);
301 this->mutex->unlock(this->mutex);
302 }
303
304 /**
305 * Implementation of kernel_interface_t.add_net_interface.
306 */
307 static void add_net_interface(private_kernel_interface_t *this,
308 kernel_net_constructor_t *create)
309 {
310 this->mutex->lock(this->mutex);
311 this->net_interfaces->insert_last(this->net_interfaces, create);
312 this->mutex->unlock(this->mutex);
313 }
314
315 /**
316 * Implementation of kernel_interface_t.remove_net_interface.
317 */
318 static void remove_net_interface(private_kernel_interface_t *this,
319 kernel_net_constructor_t *create)
320 {
321 this->mutex->lock(this->mutex);
322 this->net_interfaces->remove(this->net_interfaces, create, NULL);
323 this->mutex->unlock(this->mutex);
324 }
325
326 /**
327 * Implementation of kernel_interface_t.create_interfaces.
328 */
329 static void create_interfaces(private_kernel_interface_t *this)
330 {
331 kernel_ipsec_constructor_t create_ipsec;
332 kernel_net_constructor_t create_net;
333
334 this->mutex->lock(this->mutex);
335 if (this->ipsec_interfaces->get_first(this->ipsec_interfaces, (void**)&create_ipsec) != SUCCESS)
336 {
337 this->mutex->unlock(this->mutex);
338 charon->kill(charon, "no ipsec kernel interface loaded");
339 }
340
341 if (this->net_interfaces->get_first(this->net_interfaces, (void**)&create_net) != SUCCESS)
342 {
343 this->mutex->unlock(this->mutex);
344 charon->kill(charon, "no network kernel interface loaded");
345 }
346 this->mutex->unlock(this->mutex);
347
348 this->ipsec = create_ipsec();
349 this->net = create_net();
350 }
351
352 /**
353 * Implementation of kernel_interface_t.destroy.
354 */
355 static void destroy(private_kernel_interface_t *this)
356 {
357 DESTROY_IF(this->ipsec);
358 DESTROY_IF(this->net);
359 this->ipsec_interfaces->destroy(this->ipsec_interfaces);
360 this->net_interfaces->destroy(this->net_interfaces);
361 this->mutex->destroy(this->mutex);
362 free(this);
363 }
364
365 /*
366 * Described in header-file
367 */
368 kernel_interface_t *kernel_interface_create()
369 {
370 private_kernel_interface_t *this = malloc_thing(private_kernel_interface_t);
371
372 this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
373 this->public.get_cpi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
374 this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
375 this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
376 this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
377 this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
378 this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
379 this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy;
380
381 this->public.get_source_addr = (host_t*(*)(kernel_interface_t*, host_t *dest, host_t *src))get_source_addr;
382 this->public.get_nexthop = (host_t*(*)(kernel_interface_t*, host_t *dest))get_nexthop;
383 this->public.get_interface = (char*(*)(kernel_interface_t*,host_t*))get_interface;
384 this->public.create_address_enumerator = (enumerator_t*(*)(kernel_interface_t*,bool,bool))create_address_enumerator;
385 this->public.add_ip = (status_t(*)(kernel_interface_t*,host_t*,host_t*)) add_ip;
386 this->public.del_ip = (status_t(*)(kernel_interface_t*,host_t*)) del_ip;
387 this->public.add_route = (status_t(*)(kernel_interface_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) add_route;
388 this->public.del_route = (status_t(*)(kernel_interface_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) del_route;
389
390 this->public.get_address_by_ts = (status_t(*)(kernel_interface_t*,traffic_selector_t*,host_t**))get_address_by_ts;
391
392 this->public.add_ipsec_interface = (void(*)(kernel_interface_t*, kernel_ipsec_constructor_t))add_ipsec_interface;
393 this->public.remove_ipsec_interface = (void(*)(kernel_interface_t*, kernel_ipsec_constructor_t))remove_ipsec_interface;
394 this->public.add_net_interface = (void(*)(kernel_interface_t*, kernel_net_constructor_t))add_net_interface;
395 this->public.remove_net_interface = (void(*)(kernel_interface_t*, kernel_net_constructor_t))remove_net_interface;
396
397 this->public.create_interfaces = (void (*)(kernel_interface_t*))create_interfaces;
398 this->public.destroy = (void (*)(kernel_interface_t*))destroy;
399
400 this->ipsec_interfaces = linked_list_create();
401 this->net_interfaces = linked_list_create();
402 this->mutex = mutex_create(MUTEX_RECURSIVE);
403 this->ipsec = NULL;
404 this->net = NULL;
405
406 return &this->public;
407 }