2 * Copyright (C) 2008 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
18 #include "kernel_interface.h"
23 #include <utils/linked_list.h>
24 #include <utils/mutex.h>
26 typedef struct private_kernel_interface_t private_kernel_interface_t
;
29 * Private data of a kernel_interface_t object.
31 struct private_kernel_interface_t
{
34 * Public part of kernel_interface_t object.
36 kernel_interface_t
public;
39 * list of registered ipsec kernel interfaces
41 linked_list_t
*ipsec_interfaces
;
44 * list of registered network kernel interfaces
46 linked_list_t
*net_interfaces
;
51 kernel_ipsec_t
*ipsec
;
65 * Implementation of kernel_interface_t.get_spi
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
)
70 return this->ipsec
->get_spi(this->ipsec
, src
, dst
, protocol
, reqid
, spi
);
74 * Implementation of kernel_interface_t.get_cpi
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
)
79 return this->ipsec
->get_cpi(this->ipsec
, src
, dst
, reqid
, cpi
);
83 * Implementation of kernel_interface_t.add_sa
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
,
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
);
99 * Implementation of kernel_interface_t.update_sa
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
)
105 return this->ipsec
->update_sa(this->ipsec
, spi
, protocol
, cpi
, src
, dst
,
106 new_src
, new_dst
, encap
, new_encap
);
110 * Implementation of kernel_interface_t.del_sa
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
)
115 return this->ipsec
->del_sa(this->ipsec
, dst
, spi
, protocol
, cpi
);
119 * Implementation of kernel_interface_t.add_policy
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
,
127 return this->ipsec
->add_policy(this->ipsec
, src
, dst
, src_ts
, dst_ts
,
128 direction
, spi
, protocol
, reqid
, mode
, ipcomp
, cpi
, routed
);
132 * Implementation of kernel_interface_t.query_policy
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
)
138 return this->ipsec
->query_policy(this->ipsec
, src_ts
, dst_ts
, direction
, use_time
);
142 * Implementation of kernel_interface_t.del_policy
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
)
148 return this->ipsec
->del_policy(this->ipsec
, src_ts
, dst_ts
, direction
, unrouted
);
152 * Implementation of kernel_interface_t.get_source_addr
154 static host_t
*get_source_addr(private_kernel_interface_t
*this,
155 host_t
*dest
, host_t
*src
)
157 return this->net
->get_source_addr(this->net
, dest
, src
);
161 * Implementation of kernel_interface_t.get_nexthop
163 static host_t
*get_nexthop(private_kernel_interface_t
*this, host_t
*dest
)
165 return this->net
->get_nexthop(this->net
, dest
);
169 * Implementation of kernel_interface_t.get_interface
171 static char* get_interface(private_kernel_interface_t
*this, host_t
*host
)
173 return this->net
->get_interface(this->net
, host
);
177 * Implementation of kernel_interface_t.create_address_enumerator
179 static enumerator_t
*create_address_enumerator(private_kernel_interface_t
*this,
180 bool include_down_ifaces
, bool include_virtual_ips
)
182 return this->net
->create_address_enumerator(this->net
, include_down_ifaces
,
183 include_virtual_ips
);
187 * Implementation of kernel_interface_t.add_ip
189 static status_t
add_ip(private_kernel_interface_t
*this, host_t
*virtual_ip
,
192 return this->net
->add_ip(this->net
, virtual_ip
, iface_ip
);
196 * Implementation of kernel_interface_t.del_ip
198 static status_t
del_ip(private_kernel_interface_t
*this, host_t
*virtual_ip
)
200 return this->net
->del_ip(this->net
, virtual_ip
);
204 * Implementation of kernel_interface_t.add_route
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
)
209 return this->net
->add_route(this->net
, dst_net
, prefixlen
, gateway
, src_ip
,
214 * Implementation of kernel_interface_t.del_route
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
)
219 return this->net
->del_route(this->net
, dst_net
, prefixlen
, gateway
, src_ip
,
225 * Implementation of kernel_interface_t.get_address_by_ts
227 static status_t
get_address_by_ts(private_kernel_interface_t
*this,
228 traffic_selector_t
*ts
, host_t
**ip
)
235 DBG2(DBG_KNL
, "getting a local address in traffic selector %R", ts
);
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
;
241 if (family
== AF_INET
)
243 host
= host_create_from_string("127.0.0.1", 0);
247 host
= host_create_from_string("::1", 0);
250 if (ts
->includes(ts
, host
))
252 *ip
= host_create_any(family
);
254 DBG2(DBG_KNL
, "using host %H", *ip
);
259 addrs
= this->public.create_address_enumerator(&this->public, TRUE
, TRUE
);
260 while (addrs
->enumerate(addrs
, (void**)&host
))
262 if (ts
->includes(ts
, host
))
265 *ip
= host
->clone(host
);
269 addrs
->destroy(addrs
);
273 DBG1(DBG_KNL
, "no local address found in traffic selector %R", ts
);
277 DBG2(DBG_KNL
, "using host %H", *ip
);
283 * Implementation of kernel_interface_t.add_ipsec_interface.
285 static void add_ipsec_interface(private_kernel_interface_t
*this,
286 kernel_ipsec_constructor_t
*create
)
288 this->mutex
->lock(this->mutex
);
289 this->ipsec_interfaces
->insert_last(this->ipsec_interfaces
, create
);
290 this->mutex
->unlock(this->mutex
);
294 * Implementation of kernel_interface_t.remove_ipsec_interface.
296 static void remove_ipsec_interface(private_kernel_interface_t
*this,
297 kernel_ipsec_constructor_t
*create
)
299 this->mutex
->lock(this->mutex
);
300 this->ipsec_interfaces
->remove(this->ipsec_interfaces
, create
, NULL
);
301 this->mutex
->unlock(this->mutex
);
305 * Implementation of kernel_interface_t.add_net_interface.
307 static void add_net_interface(private_kernel_interface_t
*this,
308 kernel_net_constructor_t
*create
)
310 this->mutex
->lock(this->mutex
);
311 this->net_interfaces
->insert_last(this->net_interfaces
, create
);
312 this->mutex
->unlock(this->mutex
);
316 * Implementation of kernel_interface_t.remove_net_interface.
318 static void remove_net_interface(private_kernel_interface_t
*this,
319 kernel_net_constructor_t
*create
)
321 this->mutex
->lock(this->mutex
);
322 this->net_interfaces
->remove(this->net_interfaces
, create
, NULL
);
323 this->mutex
->unlock(this->mutex
);
327 * Implementation of kernel_interface_t.create_interfaces.
329 static void create_interfaces(private_kernel_interface_t
*this)
331 kernel_ipsec_constructor_t create_ipsec
;
332 kernel_net_constructor_t create_net
;
334 this->mutex
->lock(this->mutex
);
335 if (this->ipsec_interfaces
->get_first(this->ipsec_interfaces
, (void**)&create_ipsec
) != SUCCESS
)
337 this->mutex
->unlock(this->mutex
);
338 charon
->kill(charon
, "no ipsec kernel interface loaded");
341 if (this->net_interfaces
->get_first(this->net_interfaces
, (void**)&create_net
) != SUCCESS
)
343 this->mutex
->unlock(this->mutex
);
344 charon
->kill(charon
, "no network kernel interface loaded");
346 this->mutex
->unlock(this->mutex
);
348 this->ipsec
= create_ipsec();
349 this->net
= create_net();
353 * Implementation of kernel_interface_t.destroy.
355 static void destroy(private_kernel_interface_t
*this)
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
);
366 * Described in header-file
368 kernel_interface_t
*kernel_interface_create()
370 private_kernel_interface_t
*this = malloc_thing(private_kernel_interface_t
);
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
;
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
;
390 this->public.get_address_by_ts
= (status_t(*)(kernel_interface_t
*,traffic_selector_t
*,host_t
**))get_address_by_ts
;
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
;
397 this->public.create_interfaces
= (void (*)(kernel_interface_t
*))create_interfaces
;
398 this->public.destroy
= (void (*)(kernel_interface_t
*))destroy
;
400 this->ipsec_interfaces
= linked_list_create();
401 this->net_interfaces
= linked_list_create();
402 this->mutex
= mutex_create(MUTEX_RECURSIVE
);
406 return &this->public;