]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
support of xfrm marks for IKEv2
[thirdparty/strongswan.git] / src / libcharon / plugins / kernel_pfkey / kernel_pfkey_ipsec.c
CommitLineData
1adaa02b 1/*
668e84d9 2 * Copyright (C) 2008-2010 Tobias Brunner
c6362858 3 * Copyright (C) 2008 Andreas Steffen
1adaa02b
TB
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
1adaa02b
TB
15 */
16
17#include <sys/types.h>
18#include <sys/socket.h>
d24a74c5 19
79ff6141
TB
20#ifdef __FreeBSD__
21#include <limits.h> /* for LONG_MAX */
22#endif
23
d24a74c5
TB
24#ifdef HAVE_NET_PFKEYV2_H
25#include <net/pfkeyv2.h>
26#else
1adaa02b 27#include <stdint.h>
1adaa02b 28#include <linux/pfkeyv2.h>
d24a74c5
TB
29#endif
30
31#ifdef SADB_X_EXT_NAT_T_TYPE
32#define HAVE_NATT
33#endif
34
35#ifdef HAVE_NETIPSEC_IPSEC_H
36#include <netipsec/ipsec.h>
9f090745
TB
37#elif defined(HAVE_NETINET6_IPSEC_H)
38#include <netinet6/ipsec.h>
d24a74c5
TB
39#else
40#include <linux/ipsec.h>
41#endif
42
43#ifdef HAVE_NATT
1e7b4b00 44#ifdef HAVE_LINUX_UDP_H
1adaa02b 45#include <linux/udp.h>
1e7b4b00
TB
46#else
47#include <netinet/udp.h>
48#endif /*HAVE_LINUX_UDP_H*/
d24a74c5
TB
49#endif /*HAVE_NATT*/
50
1adaa02b 51#include <unistd.h>
4a5a5dd2 52#include <time.h>
1adaa02b
TB
53#include <errno.h>
54
55#include "kernel_pfkey_ipsec.h"
56
57#include <daemon.h>
e526d228 58#include <utils/host.h>
4a5a5dd2 59#include <threading/thread.h>
eba64cef 60#include <threading/mutex.h>
1adaa02b
TB
61#include <processing/jobs/callback_job.h>
62#include <processing/jobs/acquire_job.h>
ef6d339c 63#include <processing/jobs/migrate_job.h>
1adaa02b
TB
64#include <processing/jobs/rekey_child_sa_job.h>
65#include <processing/jobs/delete_child_sa_job.h>
66#include <processing/jobs/update_sa_job.h>
67
d24a74c5
TB
68/** non linux specific */
69#ifndef IPPROTO_COMP
b7900d32 70#ifdef IPPROTO_IPCOMP
d24a74c5
TB
71#define IPPROTO_COMP IPPROTO_IPCOMP
72#endif
b7900d32 73#endif
d24a74c5
TB
74
75#ifndef SADB_X_AALG_SHA2_256HMAC
76#define SADB_X_AALG_SHA2_256HMAC SADB_X_AALG_SHA2_256
77#define SADB_X_AALG_SHA2_384HMAC SADB_X_AALG_SHA2_384
78#define SADB_X_AALG_SHA2_512HMAC SADB_X_AALG_SHA2_512
79#endif
80
81#ifndef SADB_X_EALG_AESCBC
82#define SADB_X_EALG_AESCBC SADB_X_EALG_AES
83#endif
84
85#ifndef SADB_X_EALG_CASTCBC
86#define SADB_X_EALG_CASTCBC SADB_X_EALG_CAST128CBC
87#endif
88
89#ifndef SOL_IP
90#define SOL_IP IPPROTO_IP
91#define SOL_IPV6 IPPROTO_IPV6
92#endif
93
ea625fab
TB
94/** from linux/in.h */
95#ifndef IP_IPSEC_POLICY
96#define IP_IPSEC_POLICY 16
97#endif
98
e20bd8b6 99/** missing on uclibc */
addfea95
MW
100#ifndef IPV6_IPSEC_POLICY
101#define IPV6_IPSEC_POLICY 34
d24a74c5 102#endif
addfea95 103
1adaa02b
TB
104/** default priority of installed policies */
105#define PRIO_LOW 3000
106#define PRIO_HIGH 2000
107
e20bd8b6
TB
108#ifdef __APPLE__
109/** from xnu/bsd/net/pfkeyv2.h */
110#define SADB_X_EXT_NATT 0x002
111 struct sadb_sa_2 {
112 struct sadb_sa sa;
113 u_int16_t sadb_sa_natt_port;
114 u_int16_t sadb_reserved0;
115 u_int32_t sadb_reserved1;
116 };
117#endif
118
1adaa02b 119/** buffer size for PF_KEY messages */
e526d228 120#define PFKEY_BUFFER_SIZE 4096
1adaa02b
TB
121
122/** PF_KEY messages are 64 bit aligned */
123#define PFKEY_ALIGNMENT 8
124/** aligns len to 64 bits */
125#define PFKEY_ALIGN(len) (((len) + PFKEY_ALIGNMENT - 1) & ~(PFKEY_ALIGNMENT - 1))
126/** calculates the properly padded length in 64 bit chunks */
127#define PFKEY_LEN(len) ((PFKEY_ALIGN(len) / PFKEY_ALIGNMENT))
128/** calculates user mode length i.e. in bytes */
129#define PFKEY_USER_LEN(len) ((len) * PFKEY_ALIGNMENT)
130
131/** given a PF_KEY message header and an extension this updates the length in the header */
132#define PFKEY_EXT_ADD(msg, ext) ((msg)->sadb_msg_len += ((struct sadb_ext*)ext)->sadb_ext_len)
133/** given a PF_KEY message header this returns a pointer to the next extension */
134#define PFKEY_EXT_ADD_NEXT(msg) ((struct sadb_ext*)(((char*)(msg)) + PFKEY_USER_LEN((msg)->sadb_msg_len)))
135/** copy an extension and append it to a PF_KEY message */
136#define PFKEY_EXT_COPY(msg, ext) (PFKEY_EXT_ADD(msg, memcpy(PFKEY_EXT_ADD_NEXT(msg), ext, PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len))))
137/** given a PF_KEY extension this returns a pointer to the next extension */
138#define PFKEY_EXT_NEXT(ext) ((struct sadb_ext*)(((char*)(ext)) + PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len)))
139/** given a PF_KEY extension this returns a pointer to the next extension also updates len (len in 64 bit words) */
140#define PFKEY_EXT_NEXT_LEN(ext,len) ((len) -= (ext)->sadb_ext_len, PFKEY_EXT_NEXT(ext))
141/** true if ext has a valid length and len is large enough to contain ext (assuming len in 64 bit words) */
142#define PFKEY_EXT_OK(ext,len) ((len) >= PFKEY_LEN(sizeof(struct sadb_ext)) && \
143 (ext)->sadb_ext_len >= PFKEY_LEN(sizeof(struct sadb_ext)) && \
144 (ext)->sadb_ext_len <= (len))
145
146typedef struct private_kernel_pfkey_ipsec_t private_kernel_pfkey_ipsec_t;
147
148/**
149 * Private variables and functions of kernel_pfkey class.
150 */
151struct private_kernel_pfkey_ipsec_t
152{
153 /**
154 * Public part of the kernel_pfkey_t object.
155 */
156 kernel_pfkey_ipsec_t public;
7daf5226 157
1adaa02b
TB
158 /**
159 * mutex to lock access to various lists
160 */
3ac5a0db 161 mutex_t *mutex;
7daf5226 162
1adaa02b
TB
163 /**
164 * List of installed policies (policy_entry_t)
165 */
166 linked_list_t *policies;
7daf5226 167
1adaa02b
TB
168 /**
169 * whether to install routes along policies
170 */
171 bool install_routes;
7daf5226 172
1adaa02b
TB
173 /**
174 * job receiving PF_KEY events
175 */
176 callback_job_t *job;
7daf5226 177
1adaa02b
TB
178 /**
179 * mutex to lock access to the PF_KEY socket
180 */
3ac5a0db 181 mutex_t *mutex_pfkey;
7daf5226 182
1adaa02b
TB
183 /**
184 * PF_KEY socket to communicate with the kernel
185 */
186 int socket;
7daf5226 187
1adaa02b
TB
188 /**
189 * PF_KEY socket to receive acquire and expire events
190 */
191 int socket_events;
7daf5226 192
1adaa02b
TB
193 /**
194 * sequence number for messages sent to the kernel
195 */
196 int seq;
197};
198
199typedef struct route_entry_t route_entry_t;
200
201/**
202 * installed routing entry
203 */
204struct route_entry_t {
205 /** Name of the interface the route is bound to */
206 char *if_name;
7daf5226 207
1adaa02b
TB
208 /** Source ip of the route */
209 host_t *src_ip;
7daf5226 210
1adaa02b
TB
211 /** gateway for this route */
212 host_t *gateway;
213
214 /** Destination net */
215 chunk_t dst_net;
216
217 /** Destination net prefixlen */
218 u_int8_t prefixlen;
219};
220
221/**
222 * destroy an route_entry_t object
223 */
224static void route_entry_destroy(route_entry_t *this)
225{
226 free(this->if_name);
d24a74c5
TB
227 DESTROY_IF(this->src_ip);
228 DESTROY_IF(this->gateway);
1adaa02b
TB
229 chunk_free(&this->dst_net);
230 free(this);
231}
232
233typedef struct policy_entry_t policy_entry_t;
234
235/**
236 * installed kernel policy.
237 */
238struct policy_entry_t {
7daf5226 239
1adaa02b
TB
240 /** reqid of this policy */
241 u_int32_t reqid;
7daf5226 242
1adaa02b
TB
243 /** index assigned by the kernel */
244 u_int32_t index;
7daf5226 245
1adaa02b
TB
246 /** direction of this policy: in, out, forward */
247 u_int8_t direction;
7daf5226 248
1adaa02b
TB
249 /** parameters of installed policy */
250 struct {
251 /** subnet and port */
252 host_t *net;
253 /** subnet mask */
254 u_int8_t mask;
255 /** protocol */
256 u_int8_t proto;
257 } src, dst;
7daf5226 258
1adaa02b
TB
259 /** associated route installed for this policy */
260 route_entry_t *route;
7daf5226 261
1adaa02b
TB
262 /** by how many CHILD_SA's this policy is used */
263 u_int refcount;
264};
265
266/**
267 * create a policy_entry_t object
268 */
269static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts,
270 traffic_selector_t *dst_ts, policy_dir_t dir, u_int32_t reqid)
271{
272 policy_entry_t *policy = malloc_thing(policy_entry_t);
273 policy->reqid = reqid;
274 policy->index = 0;
275 policy->direction = dir;
276 policy->route = NULL;
277 policy->refcount = 0;
7daf5226 278
1adaa02b
TB
279 src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask);
280 dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask);
7daf5226 281
1adaa02b
TB
282 /* src or dest proto may be "any" (0), use more restrictive one */
283 policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts));
d24a74c5 284 policy->src.proto = policy->src.proto ? policy->src.proto : IPSEC_PROTO_ANY;
1adaa02b 285 policy->dst.proto = policy->src.proto;
7daf5226 286
1adaa02b
TB
287 return policy;
288}
289
290/**
291 * destroy a policy_entry_t object
292 */
293static void policy_entry_destroy(policy_entry_t *this)
294{
295 DESTROY_IF(this->src.net);
296 DESTROY_IF(this->dst.net);
297 if (this->route)
298 {
299 route_entry_destroy(this->route);
300 }
301 free(this);
302}
303
304/**
305 * compares two policy_entry_t
306 */
307static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *policy)
308{
309 return current->direction == policy->direction &&
310 current->src.proto == policy->src.proto &&
311 current->dst.proto == policy->dst.proto &&
312 current->src.mask == policy->src.mask &&
313 current->dst.mask == policy->dst.mask &&
314 current->src.net->equals(current->src.net, policy->src.net) &&
315 current->dst.net->equals(current->dst.net, policy->dst.net);
316}
317
318/**
319 * compare the given kernel index with that of a policy
320 */
321static inline bool policy_entry_match_byindex(policy_entry_t *current, u_int32_t *index)
322{
323 return current->index == *index;
324}
325
326typedef struct pfkey_msg_t pfkey_msg_t;
327
328struct pfkey_msg_t
329{
330 /**
331 * PF_KEY message base
332 */
333 struct sadb_msg *msg;
7daf5226 334
1adaa02b
TB
335 /**
336 * PF_KEY message extensions
337 */
338 union {
339 struct sadb_ext *ext[SADB_EXT_MAX + 1];
340 struct {
341 struct sadb_ext *reserved; /* SADB_EXT_RESERVED */
342 struct sadb_sa *sa; /* SADB_EXT_SA */
343 struct sadb_lifetime *lft_current; /* SADB_EXT_LIFETIME_CURRENT */
344 struct sadb_lifetime *lft_hard; /* SADB_EXT_LIFETIME_HARD */
345 struct sadb_lifetime *lft_soft; /* SADB_EXT_LIFETIME_SOFT */
346 struct sadb_address *src; /* SADB_EXT_ADDRESS_SRC */
347 struct sadb_address *dst; /* SADB_EXT_ADDRESS_DST */
348 struct sadb_address *proxy; /* SADB_EXT_ADDRESS_PROXY */
349 struct sadb_key *key_auth; /* SADB_EXT_KEY_AUTH */
350 struct sadb_key *key_encr; /* SADB_EXT_KEY_ENCRYPT */
351 struct sadb_ident *id_src; /* SADB_EXT_IDENTITY_SRC */
352 struct sadb_ident *id_dst; /* SADB_EXT_IDENTITY_DST */
353 struct sadb_sens *sensitivity; /* SADB_EXT_SENSITIVITY */
354 struct sadb_prop *proposal; /* SADB_EXT_PROPOSAL */
355 struct sadb_supported *supported_auth; /* SADB_EXT_SUPPORTED_AUTH */
356 struct sadb_supported *supported_encr; /* SADB_EXT_SUPPORTED_ENCRYPT */
357 struct sadb_spirange *spirange; /* SADB_EXT_SPIRANGE */
358 struct sadb_x_kmprivate *x_kmprivate; /* SADB_X_EXT_KMPRIVATE */
359 struct sadb_x_policy *x_policy; /* SADB_X_EXT_POLICY */
360 struct sadb_x_sa2 *x_sa2; /* SADB_X_EXT_SA2 */
361 struct sadb_x_nat_t_type *x_natt_type; /* SADB_X_EXT_NAT_T_TYPE */
362 struct sadb_x_nat_t_port *x_natt_sport; /* SADB_X_EXT_NAT_T_SPORT */
363 struct sadb_x_nat_t_port *x_natt_dport; /* SADB_X_EXT_NAT_T_DPORT */
364 struct sadb_address *x_natt_oa; /* SADB_X_EXT_NAT_T_OA */
365 struct sadb_x_sec_ctx *x_sec_ctx; /* SADB_X_EXT_SEC_CTX */
e526d228 366 struct sadb_x_kmaddress *x_kmaddress; /* SADB_X_EXT_KMADDRESS */
1adaa02b
TB
367 } __attribute__((__packed__));
368 };
369};
370
d24a74c5 371ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_EXT_MAX,
e526d228
AS
372 "SADB_EXT_RESERVED",
373 "SADB_EXT_SA",
374 "SADB_EXT_LIFETIME_CURRENT",
375 "SADB_EXT_LIFETIME_HARD",
376 "SADB_EXT_LIFETIME_SOFT",
377 "SADB_EXT_ADDRESS_SRC",
378 "SADB_EXT_ADDRESS_DST",
379 "SADB_EXT_ADDRESS_PROXY",
380 "SADB_EXT_KEY_AUTH",
381 "SADB_EXT_KEY_ENCRYPT",
382 "SADB_EXT_IDENTITY_SRC",
383 "SADB_EXT_IDENTITY_DST",
384 "SADB_EXT_SENSITIVITY",
385 "SADB_EXT_PROPOSAL",
386 "SADB_EXT_SUPPORTED_AUTH",
387 "SADB_EXT_SUPPORTED_ENCRYPT",
388 "SADB_EXT_SPIRANGE",
389 "SADB_X_EXT_KMPRIVATE",
390 "SADB_X_EXT_POLICY",
391 "SADB_X_EXT_SA2",
392 "SADB_X_EXT_NAT_T_TYPE",
393 "SADB_X_EXT_NAT_T_SPORT",
394 "SADB_X_EXT_NAT_T_DPORT",
395 "SADB_X_EXT_NAT_T_OA",
396 "SADB_X_EXT_SEC_CTX",
397 "SADB_X_EXT_KMADDRESS"
398);
d24a74c5 399
1adaa02b
TB
400/**
401 * convert a IKEv2 specific protocol identifier to the PF_KEY sa type
402 */
403static u_int8_t proto_ike2satype(protocol_id_t proto)
404{
405 switch (proto)
406 {
407 case PROTO_ESP:
408 return SADB_SATYPE_ESP;
409 case PROTO_AH:
410 return SADB_SATYPE_AH;
411 case IPPROTO_COMP:
412 return SADB_X_SATYPE_IPCOMP;
413 default:
414 return proto;
415 }
416}
417
418/**
419 * convert a PF_KEY sa type to a IKEv2 specific protocol identifier
420 */
421static protocol_id_t proto_satype2ike(u_int8_t proto)
422{
423 switch (proto)
424 {
425 case SADB_SATYPE_ESP:
426 return PROTO_ESP;
427 case SADB_SATYPE_AH:
428 return PROTO_AH;
429 case SADB_X_SATYPE_IPCOMP:
430 return IPPROTO_COMP;
431 default:
432 return proto;
433 }
434}
435
436/**
437 * convert a IKEv2 specific protocol identifier to the IP protocol identifier
438 */
439static u_int8_t proto_ike2ip(protocol_id_t proto)
440{
441 switch (proto)
442 {
443 case PROTO_ESP:
444 return IPPROTO_ESP;
445 case PROTO_AH:
446 return IPPROTO_AH;
447 default:
448 return proto;
449 }
450}
451
452/**
453 * convert the general ipsec mode to the one defined in ipsec.h
454 */
455static u_int8_t mode2kernel(ipsec_mode_t mode)
456{
457 switch (mode)
458 {
459 case MODE_TRANSPORT:
460 return IPSEC_MODE_TRANSPORT;
461 case MODE_TUNNEL:
462 return IPSEC_MODE_TUNNEL;
617e59b7 463#ifdef HAVE_IPSEC_MODE_BEET
1adaa02b
TB
464 case MODE_BEET:
465 return IPSEC_MODE_BEET;
d24a74c5 466#endif
1adaa02b
TB
467 default:
468 return mode;
469 }
470}
471
472/**
473 * convert the general policy direction to the one defined in ipsec.h
474 */
475static u_int8_t dir2kernel(policy_dir_t dir)
476{
477 switch (dir)
478 {
479 case POLICY_IN:
480 return IPSEC_DIR_INBOUND;
481 case POLICY_OUT:
482 return IPSEC_DIR_OUTBOUND;
617e59b7 483#ifdef HAVE_IPSEC_DIR_FWD
1adaa02b
TB
484 case POLICY_FWD:
485 return IPSEC_DIR_FWD;
d24a74c5 486#endif
1adaa02b 487 default:
eab05274 488 return IPSEC_DIR_INVALID;
1adaa02b
TB
489 }
490}
491
d24a74c5 492#ifdef SADB_X_MIGRATE
5145ae48
AS
493/**
494 * convert the policy direction in ipsec.h to the general one.
495 */
496static policy_dir_t kernel2dir(u_int8_t dir)
497{
498 switch (dir)
499 {
500 case IPSEC_DIR_INBOUND:
501 return POLICY_IN;
502 case IPSEC_DIR_OUTBOUND:
503 return POLICY_OUT;
617e59b7 504#ifdef HAVE_IPSEC_DIR_FWD
5145ae48
AS
505 case IPSEC_DIR_FWD:
506 return POLICY_FWD;
d24a74c5 507#endif
5145ae48
AS
508 default:
509 return dir;
510 }
511}
d24a74c5
TB
512#endif /*SADB_X_MIGRATE*/
513
1adaa02b
TB
514typedef struct kernel_algorithm_t kernel_algorithm_t;
515
516/**
e517b4b1 517 * Mapping of IKEv2 algorithms to PF_KEY algorithms
1adaa02b
TB
518 */
519struct kernel_algorithm_t {
520 /**
521 * Identifier specified in IKEv2
522 */
e517b4b1 523 int ikev2;
7daf5226 524
1adaa02b
TB
525 /**
526 * Identifier as defined in pfkeyv2.h
527 */
e517b4b1 528 int kernel;
1adaa02b
TB
529};
530
531#define END_OF_LIST -1
532
533/**
534 * Algorithms for encryption
535 */
536static kernel_algorithm_t encryption_algs[] = {
d24a74c5
TB
537/* {ENCR_DES_IV64, 0 }, */
538 {ENCR_DES, SADB_EALG_DESCBC },
539 {ENCR_3DES, SADB_EALG_3DESCBC },
540/* {ENCR_RC5, 0 }, */
541/* {ENCR_IDEA, 0 }, */
542 {ENCR_CAST, SADB_X_EALG_CASTCBC },
543 {ENCR_BLOWFISH, SADB_X_EALG_BLOWFISHCBC },
544/* {ENCR_3IDEA, 0 }, */
545/* {ENCR_DES_IV32, 0 }, */
546 {ENCR_NULL, SADB_EALG_NULL },
547 {ENCR_AES_CBC, SADB_X_EALG_AESCBC },
548/* {ENCR_AES_CTR, SADB_X_EALG_AESCTR }, */
e526d228
AS
549/* {ENCR_AES_CCM_ICV8, SADB_X_EALG_AES_CCM_ICV8 }, */
550/* {ENCR_AES_CCM_ICV12, SADB_X_EALG_AES_CCM_ICV12 }, */
551/* {ENCR_AES_CCM_ICV16, SADB_X_EALG_AES_CCM_ICV16 }, */
552/* {ENCR_AES_GCM_ICV8, SADB_X_EALG_AES_GCM_ICV8 }, */
553/* {ENCR_AES_GCM_ICV12, SADB_X_EALG_AES_GCM_ICV12 }, */
554/* {ENCR_AES_GCM_ICV16, SADB_X_EALG_AES_GCM_ICV16 }, */
d24a74c5 555 {END_OF_LIST, 0 },
1adaa02b
TB
556};
557
558/**
559 * Algorithms for integrity protection
560 */
561static kernel_algorithm_t integrity_algs[] = {
d24a74c5 562 {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC },
e517b4b1
MW
563 {AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC },
564 {AUTH_HMAC_SHA2_256_128, SADB_X_AALG_SHA2_256HMAC },
565 {AUTH_HMAC_SHA2_384_192, SADB_X_AALG_SHA2_384HMAC },
566 {AUTH_HMAC_SHA2_512_256, SADB_X_AALG_SHA2_512HMAC },
567/* {AUTH_DES_MAC, 0, }, */
568/* {AUTH_KPDK_MD5, 0, }, */
7cdb1ddf 569#ifdef SADB_X_AALG_AES_XCBC_MAC
e517b4b1 570 {AUTH_AES_XCBC_96, SADB_X_AALG_AES_XCBC_MAC, },
7cdb1ddf 571#endif
d24a74c5 572 {END_OF_LIST, 0, },
1adaa02b
TB
573};
574
3d2dbebd 575#if 0
1adaa02b 576/**
3d2dbebd 577 * Algorithms for IPComp, unused yet
1adaa02b
TB
578 */
579static kernel_algorithm_t compression_algs[] = {
d24a74c5 580/* {IPCOMP_OUI, 0 }, */
e517b4b1
MW
581 {IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE },
582 {IPCOMP_LZS, SADB_X_CALG_LZS },
583 {IPCOMP_LZJH, SADB_X_CALG_LZJH },
d24a74c5 584 {END_OF_LIST, 0 },
1adaa02b 585};
3d2dbebd 586#endif
1adaa02b
TB
587
588/**
589 * Look up a kernel algorithm ID and its key size
590 */
e517b4b1 591static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
1adaa02b 592{
e517b4b1 593 while (list->ikev2 != END_OF_LIST)
1adaa02b 594 {
e517b4b1 595 if (ikev2 == list->ikev2)
1adaa02b 596 {
e517b4b1 597 return list->kernel;
1adaa02b 598 }
e517b4b1 599 list++;
1adaa02b
TB
600 }
601 return 0;
602}
603
604/**
668e84d9
TB
605 * Copy a host_t as sockaddr_t to the given memory location. Ports are
606 * reset to zero as per RFC 2367.
607 * @return the number of bytes copied
1adaa02b 608 */
668e84d9 609static size_t hostcpy(void *dest, host_t *host)
1adaa02b 610{
668e84d9 611 sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest;
1adaa02b 612 socklen_t *len = host->get_sockaddr_len(host);
668e84d9 613 memcpy(dest, addr, *len);
d24a74c5 614#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
668e84d9 615 dest_addr->sa_len = *len;
d24a74c5 616#endif
668e84d9
TB
617 switch (dest_addr->sa_family)
618 {
619 case AF_INET:
620 {
621 struct sockaddr_in *sin = dest;
622 sin->sin_port = 0;
623 break;
624 }
625 case AF_INET6:
626 {
627 struct sockaddr_in6 *sin6 = dest;
628 sin6->sin6_port = 0;
629 break;
630 }
631 }
632 return *len;
633}
634
635/**
636 * add a host behind an sadb_address extension
637 */
638static void host2ext(host_t *host, struct sadb_address *ext)
639{
640 size_t len = hostcpy(ext + 1, host);
641 ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + len);
1adaa02b
TB
642}
643
f55a7a76
TB
644/**
645 * add a host to the given sadb_msg
646 */
647static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type,
648 u_int8_t proto, u_int8_t prefixlen)
649{
650 struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
651 addr->sadb_address_exttype = type;
652 addr->sadb_address_proto = proto;
653 addr->sadb_address_prefixlen = prefixlen;
654 host2ext(host, addr);
655 PFKEY_EXT_ADD(msg, addr);
656}
657
658/**
659 * adds an empty address extension to the given sadb_msg
660 */
661static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type)
662{
663 socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) :
664 sizeof(struct sockaddr_in6);
665 struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
666 addr->sadb_address_exttype = type;
667 sockaddr_t *saddr = (sockaddr_t*)(addr + 1);
668 saddr->sa_family = family;
d24a74c5
TB
669#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
670 saddr->sa_len = len;
671#endif
672 addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len);
f55a7a76
TB
673 PFKEY_EXT_ADD(msg, addr);
674}
675
d24a74c5 676#ifdef HAVE_NATT
1adaa02b
TB
677/**
678 * add udp encap extensions to a sadb_msg
679 */
680static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst)
681{
682 struct sadb_x_nat_t_type* nat_type;
683 struct sadb_x_nat_t_port* nat_port;
7daf5226 684
1adaa02b
TB
685 nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg);
686 nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
687 nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_type));
688 nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP;
689 PFKEY_EXT_ADD(msg, nat_type);
7daf5226 690
1adaa02b
TB
691 nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
692 nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
693 nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
694 nat_port->sadb_x_nat_t_port_port = htons(src->get_port(src));
695 PFKEY_EXT_ADD(msg, nat_port);
7daf5226 696
1adaa02b
TB
697 nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
698 nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
699 nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
700 nat_port->sadb_x_nat_t_port_port = htons(dst->get_port(dst));
701 PFKEY_EXT_ADD(msg, nat_port);
702}
d24a74c5 703#endif /*HAVE_NATT*/
1adaa02b 704
e526d228
AS
705/**
706 * Convert a sadb_address to a traffic_selector
707 */
708static traffic_selector_t* sadb_address2ts(struct sadb_address *address)
709{
710 traffic_selector_t *ts;
e526d228 711 host_t *host;
e526d228
AS
712
713 /* The Linux 2.6 kernel does not set the protocol and port information
323f9f99
MW
714 * in the src and dst sadb_address extensions of the SADB_ACQUIRE message.
715 */
e526d228 716 host = host_create_from_sockaddr((sockaddr_t*)&address[1]) ;
5145ae48 717 ts = traffic_selector_create_from_subnet(host, address->sadb_address_prefixlen,
d24a74c5 718 address->sadb_address_proto, host->get_port(host));
e526d228
AS
719 return ts;
720}
721
1adaa02b
TB
722/**
723 * Parses a pfkey message received from the kernel
724 */
725static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out)
726{
727 struct sadb_ext* ext;
728 size_t len;
7daf5226 729
1adaa02b
TB
730 memset(out, 0, sizeof(pfkey_msg_t));
731 out->msg = msg;
7daf5226 732
1adaa02b
TB
733 len = msg->sadb_msg_len;
734 len -= PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 735
1adaa02b 736 ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg));
7daf5226 737
1adaa02b
TB
738 while (len >= PFKEY_LEN(sizeof(struct sadb_ext)))
739 {
bfca7aa5 740 DBG3(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type);
1adaa02b
TB
741 if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) ||
742 ext->sadb_ext_len > len)
743 {
e526d228
AS
744 DBG1(DBG_KNL, "length of %N extension is invalid",
745 sadb_ext_type_names, ext->sadb_ext_type);
1adaa02b
TB
746 break;
747 }
7daf5226 748
1adaa02b
TB
749 if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type))
750 {
751 DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", ext->sadb_ext_type);
752 break;
753 }
7daf5226 754
1adaa02b
TB
755 if (out->ext[ext->sadb_ext_type])
756 {
d24a74c5 757 DBG1(DBG_KNL, "duplicate %N extension",
e526d228 758 sadb_ext_type_names, ext->sadb_ext_type);
1adaa02b
TB
759 break;
760 }
7daf5226 761
1adaa02b
TB
762 out->ext[ext->sadb_ext_type] = ext;
763 ext = PFKEY_EXT_NEXT_LEN(ext, len);
764 }
765
766 if (len)
767 {
768 DBG1(DBG_KNL, "PF_KEY message length is invalid");
769 return FAILED;
770 }
7daf5226 771
1adaa02b
TB
772 return SUCCESS;
773}
774
775/**
776 * Send a message to a specific PF_KEY socket and handle the response.
777 */
778static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket,
779 struct sadb_msg *in, struct sadb_msg **out, size_t *out_len)
780{
781 unsigned char buf[PFKEY_BUFFER_SIZE];
782 struct sadb_msg *msg;
783 int in_len, len;
7daf5226 784
3ac5a0db 785 this->mutex_pfkey->lock(this->mutex_pfkey);
1adaa02b 786
56ee8fcc
TB
787 /* FIXME: our usage of sequence numbers is probably wrong. check RFC 2367,
788 * in particular the behavior in response to an SADB_ACQUIRE. */
1adaa02b
TB
789 in->sadb_msg_seq = ++this->seq;
790 in->sadb_msg_pid = getpid();
791
792 in_len = PFKEY_USER_LEN(in->sadb_msg_len);
793
794 while (TRUE)
795 {
796 len = send(socket, in, in_len, 0);
797
798 if (len != in_len)
799 {
800 if (errno == EINTR)
801 {
802 /* interrupted, try again */
803 continue;
804 }
3ac5a0db 805 this->mutex_pfkey->unlock(this->mutex_pfkey);
1adaa02b
TB
806 DBG1(DBG_KNL, "error sending to PF_KEY socket: %s", strerror(errno));
807 return FAILED;
808 }
809 break;
810 }
7daf5226 811
1adaa02b 812 while (TRUE)
d24a74c5 813 {
1adaa02b 814 msg = (struct sadb_msg*)buf;
7daf5226 815
1adaa02b 816 len = recv(socket, buf, sizeof(buf), 0);
7daf5226 817
1adaa02b
TB
818 if (len < 0)
819 {
820 if (errno == EINTR)
821 {
822 DBG1(DBG_KNL, "got interrupted");
823 /* interrupted, try again */
824 continue;
825 }
826 DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", strerror(errno));
3ac5a0db 827 this->mutex_pfkey->unlock(this->mutex_pfkey);
1adaa02b
TB
828 return FAILED;
829 }
830 if (len < sizeof(struct sadb_msg) ||
831 msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg)))
832 {
833 DBG1(DBG_KNL, "received corrupted PF_KEY message");
3ac5a0db 834 this->mutex_pfkey->unlock(this->mutex_pfkey);
1adaa02b
TB
835 return FAILED;
836 }
837 if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
838 {
839 DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
3ac5a0db 840 this->mutex_pfkey->unlock(this->mutex_pfkey);
1adaa02b
TB
841 return FAILED;
842 }
843 if (msg->sadb_msg_pid != in->sadb_msg_pid)
844 {
845 DBG2(DBG_KNL, "received PF_KEY message is not intended for us");
846 continue;
847 }
848 if (msg->sadb_msg_seq != this->seq)
849 {
56ee8fcc
TB
850 DBG1(DBG_KNL, "received PF_KEY message with unexpected sequence "
851 "number, was %d expected %d", msg->sadb_msg_seq, this->seq);
852 if (msg->sadb_msg_seq == 0)
853 {
854 /* FreeBSD and Mac OS X do this for the response to
855 * SADB_X_SPDGET (but not for the response to SADB_GET).
856 * FreeBSD: 'key_spdget' in /usr/src/sys/netipsec/key.c. */
857 }
858 else if (msg->sadb_msg_seq < this->seq)
1adaa02b
TB
859 {
860 continue;
861 }
56ee8fcc
TB
862 else
863 {
864 this->mutex_pfkey->unlock(this->mutex_pfkey);
865 return FAILED;
866 }
1adaa02b
TB
867 }
868 if (msg->sadb_msg_type != in->sadb_msg_type)
869 {
870 DBG2(DBG_KNL, "received PF_KEY message of wrong type, "
871 "was %d expected %d, ignoring",
872 msg->sadb_msg_type, in->sadb_msg_type);
873 }
874 break;
875 }
7daf5226 876
1adaa02b
TB
877 *out_len = len;
878 *out = (struct sadb_msg*)malloc(len);
879 memcpy(*out, buf, len);
7daf5226 880
3ac5a0db 881 this->mutex_pfkey->unlock(this->mutex_pfkey);
7daf5226 882
1adaa02b
TB
883 return SUCCESS;
884}
885
886/**
887 * Send a message to the default PF_KEY socket and handle the response.
888 */
889static status_t pfkey_send(private_kernel_pfkey_ipsec_t *this,
890 struct sadb_msg *in, struct sadb_msg **out, size_t *out_len)
891{
892 return pfkey_send_socket(this, this->socket, in, out, out_len);
893}
894
895/**
896 * Process a SADB_ACQUIRE message from the kernel
897 */
898static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
899{
900 pfkey_msg_t response;
e526d228
AS
901 u_int32_t index, reqid = 0;
902 traffic_selector_t *src_ts, *dst_ts;
1adaa02b
TB
903 policy_entry_t *policy;
904 job_t *job;
7daf5226 905
1adaa02b
TB
906 switch (msg->sadb_msg_satype)
907 {
908 case SADB_SATYPE_UNSPEC:
909 case SADB_SATYPE_ESP:
910 case SADB_SATYPE_AH:
911 break;
912 default:
913 /* acquire for AH/ESP only */
914 return;
915 }
e526d228 916 DBG2(DBG_KNL, "received an SADB_ACQUIRE");
7daf5226 917
1adaa02b
TB
918 if (parse_pfkey_message(msg, &response) != SUCCESS)
919 {
920 DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed");
921 return;
922 }
7daf5226 923
1adaa02b 924 index = response.x_policy->sadb_x_policy_id;
3ac5a0db 925 this->mutex->lock(this->mutex);
1adaa02b 926 if (this->policies->find_first(this->policies,
e526d228 927 (linked_list_match_t)policy_entry_match_byindex, (void**)&policy, &index) == SUCCESS)
1adaa02b 928 {
e526d228
AS
929 reqid = policy->reqid;
930 }
931 else
932 {
933 DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no matching policy found",
934 index);
1adaa02b 935 }
e526d228
AS
936 src_ts = sadb_address2ts(response.src);
937 dst_ts = sadb_address2ts(response.dst);
3ac5a0db 938 this->mutex->unlock(this->mutex);
7daf5226 939
ef6d339c
AS
940 DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}",
941 src_ts, dst_ts, reqid);
e526d228 942 job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts);
1adaa02b
TB
943 charon->processor->queue_job(charon->processor, job);
944}
945
946/**
947 * Process a SADB_EXPIRE message from the kernel
948 */
949static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
950{
951 pfkey_msg_t response;
952 protocol_id_t protocol;
953 u_int32_t spi, reqid;
954 bool hard;
955 job_t *job;
7daf5226 956
1adaa02b 957 DBG2(DBG_KNL, "received an SADB_EXPIRE");
7daf5226 958
1adaa02b
TB
959 if (parse_pfkey_message(msg, &response) != SUCCESS)
960 {
961 DBG1(DBG_KNL, "parsing SADB_EXPIRE from kernel failed");
962 return;
963 }
7daf5226 964
1adaa02b
TB
965 protocol = proto_satype2ike(msg->sadb_msg_satype);
966 spi = response.sa->sadb_sa_spi;
967 reqid = response.x_sa2->sadb_x_sa2_reqid;
968 hard = response.lft_hard != NULL;
7daf5226 969
1adaa02b
TB
970 if (protocol != PROTO_ESP && protocol != PROTO_AH)
971 {
ef6d339c 972 DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%u} "
1adaa02b
TB
973 "which is not a CHILD_SA", ntohl(spi), reqid);
974 return;
975 }
7daf5226 976
ef6d339c 977 DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
1adaa02b
TB
978 hard ? "delete" : "rekey", protocol_id_names,
979 protocol, ntohl(spi), reqid);
980 if (hard)
981 {
982 job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi);
983 }
984 else
985 {
986 job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi);
987 }
988 charon->processor->queue_job(charon->processor, job);
989}
990
d24a74c5 991#ifdef SADB_X_MIGRATE
e526d228 992/**
d24a74c5 993 * Process a SADB_X_MIGRATE message from the kernel
e526d228
AS
994 */
995static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
996{
997 pfkey_msg_t response;
5145ae48
AS
998 traffic_selector_t *src_ts, *dst_ts;
999 policy_dir_t dir;
f11a54bc
AS
1000 u_int32_t reqid = 0;
1001 host_t *local = NULL, *remote = NULL;
ef6d339c 1002 job_t *job;
e526d228
AS
1003
1004 DBG2(DBG_KNL, "received an SADB_X_MIGRATE");
1005
1006 if (parse_pfkey_message(msg, &response) != SUCCESS)
1007 {
1008 DBG1(DBG_KNL, "parsing SADB_X_MIGRATE from kernel failed");
1009 return;
1010 }
5145ae48
AS
1011 src_ts = sadb_address2ts(response.src);
1012 dst_ts = sadb_address2ts(response.dst);
5145ae48
AS
1013 dir = kernel2dir(response.x_policy->sadb_x_policy_dir);
1014 DBG2(DBG_KNL, " policy %R === %R %N, id %u", src_ts, dst_ts,
7a915d62 1015 policy_dir_names, dir);
7daf5226 1016
d24a74c5 1017 /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */
f11a54bc
AS
1018 if (response.x_kmaddress)
1019 {
1020 sockaddr_t *local_addr, *remote_addr;
1021 u_int32_t local_len;
1022
1023 local_addr = (sockaddr_t*)&response.x_kmaddress[1];
1024 local = host_create_from_sockaddr(local_addr);
1025 local_len = (local_addr->sa_family == AF_INET6)?
1026 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
1027 remote_addr = (sockaddr_t*)((u_int8_t*)local_addr + local_len);
1028 remote = host_create_from_sockaddr(remote_addr);
1029 DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote);
1030 }
7daf5226 1031
7a915d62 1032 if (src_ts && dst_ts && local && remote)
ef6d339c 1033 {
bab075b1 1034 DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
ef6d339c 1035 src_ts, dst_ts, policy_dir_names, dir, reqid, local);
bab075b1 1036 job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir,
2c815393 1037 local, remote);
ef6d339c
AS
1038 charon->processor->queue_job(charon->processor, job);
1039 }
1040 else
1041 {
1042 DESTROY_IF(src_ts);
1043 DESTROY_IF(dst_ts);
1044 DESTROY_IF(local);
2c815393 1045 DESTROY_IF(remote);
ef6d339c 1046 }
e526d228 1047}
d24a74c5 1048#endif /*SADB_X_MIGRATE*/
e526d228 1049
ed76b216 1050#ifdef SADB_X_NAT_T_NEW_MAPPING
1adaa02b
TB
1051/**
1052 * Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel
1053 */
1054static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
1055{
1056 pfkey_msg_t response;
1057 u_int32_t spi, reqid;
1058 host_t *host;
1059 job_t *job;
7daf5226 1060
1adaa02b 1061 DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING");
7daf5226 1062
1adaa02b
TB
1063 if (parse_pfkey_message(msg, &response) != SUCCESS)
1064 {
1065 DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed");
1066 return;
1067 }
7daf5226 1068
1adaa02b
TB
1069 if (!response.x_sa2)
1070 {
1071 DBG1(DBG_KNL, "received SADB_X_NAT_T_NEW_MAPPING is missing required information");
1072 return;
1073 }
7daf5226 1074
1adaa02b
TB
1075 spi = response.sa->sadb_sa_spi;
1076 reqid = response.x_sa2->sadb_x_sa2_reqid;
7daf5226 1077
1adaa02b
TB
1078 if (proto_satype2ike(msg->sadb_msg_satype) == PROTO_ESP)
1079 {
1080 sockaddr_t *sa = (sockaddr_t*)(response.dst + 1);
1081 switch (sa->sa_family)
1082 {
1083 case AF_INET:
1084 {
1085 struct sockaddr_in *sin = (struct sockaddr_in*)sa;
ea625fab 1086 sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
1adaa02b
TB
1087 }
1088 case AF_INET6:
1089 {
1090 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
ea625fab 1091 sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
1adaa02b
TB
1092 }
1093 default:
1094 break;
1095 }
1096 host = host_create_from_sockaddr(sa);
1097 if (host)
1098 {
1099 DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and "
ef6d339c 1100 "reqid {%u} changed, queuing update job", ntohl(spi), reqid);
1adaa02b
TB
1101 job = (job_t*)update_sa_job_create(reqid, host);
1102 charon->processor->queue_job(charon->processor, job);
1103 }
1104 }
1105}
ed76b216 1106#endif /*SADB_X_NAT_T_NEW_MAPPING*/
1adaa02b
TB
1107
1108/**
1109 * Receives events from kernel
1110 */
1111static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this)
1112{
1113 unsigned char buf[PFKEY_BUFFER_SIZE];
1114 struct sadb_msg *msg = (struct sadb_msg*)buf;
4a5a5dd2
TB
1115 int len;
1116 bool oldstate;
7daf5226 1117
4a5a5dd2 1118 oldstate = thread_cancelability(TRUE);
d24a74c5 1119 len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0);
4a5a5dd2 1120 thread_cancelability(oldstate);
7daf5226 1121
1adaa02b
TB
1122 if (len < 0)
1123 {
1124 switch (errno)
1125 {
1126 case EINTR:
1127 /* interrupted, try again */
1128 return JOB_REQUEUE_DIRECT;
1129 case EAGAIN:
1130 /* no data ready, select again */
1131 return JOB_REQUEUE_DIRECT;
1132 default:
1133 DBG1(DBG_KNL, "unable to receive from PF_KEY event socket");
1134 sleep(1);
1135 return JOB_REQUEUE_FAIR;
1136 }
1137 }
7daf5226 1138
1adaa02b
TB
1139 if (len < sizeof(struct sadb_msg) ||
1140 msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg)))
1141 {
1142 DBG2(DBG_KNL, "received corrupted PF_KEY message");
1143 return JOB_REQUEUE_DIRECT;
1144 }
1145 if (msg->sadb_msg_pid != 0)
1146 { /* not from kernel. not interested, try another one */
1147 return JOB_REQUEUE_DIRECT;
1148 }
1149 if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
1150 {
1151 DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
1152 return JOB_REQUEUE_DIRECT;
1153 }
7daf5226 1154
1adaa02b
TB
1155 switch (msg->sadb_msg_type)
1156 {
1157 case SADB_ACQUIRE:
1158 process_acquire(this, msg);
1159 break;
1160 case SADB_EXPIRE:
1161 process_expire(this, msg);
1162 break;
d24a74c5 1163#ifdef SADB_X_MIGRATE
e526d228
AS
1164 case SADB_X_MIGRATE:
1165 process_migrate(this, msg);
1166 break;
d24a74c5 1167#endif /*SADB_X_MIGRATE*/
ed76b216 1168#ifdef SADB_X_NAT_T_NEW_MAPPING
1adaa02b
TB
1169 case SADB_X_NAT_T_NEW_MAPPING:
1170 process_mapping(this, msg);
1171 break;
ed76b216 1172#endif /*SADB_X_NAT_T_NEW_MAPPING*/
1adaa02b
TB
1173 default:
1174 break;
1175 }
7daf5226 1176
1adaa02b
TB
1177 return JOB_REQUEUE_DIRECT;
1178}
1179
44791b75
MW
1180METHOD(kernel_ipsec_t, get_spi, status_t,
1181 private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
1182 protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
1adaa02b
TB
1183{
1184 unsigned char request[PFKEY_BUFFER_SIZE];
1185 struct sadb_msg *msg, *out;
1adaa02b 1186 struct sadb_x_sa2 *sa2;
1adaa02b
TB
1187 struct sadb_spirange *range;
1188 pfkey_msg_t response;
1189 u_int32_t received_spi = 0;
1190 size_t len;
7daf5226 1191
1adaa02b 1192 memset(&request, 0, sizeof(request));
7daf5226 1193
1adaa02b
TB
1194 msg = (struct sadb_msg*)request;
1195 msg->sadb_msg_version = PF_KEY_V2;
1196 msg->sadb_msg_type = SADB_GETSPI;
1197 msg->sadb_msg_satype = proto_ike2satype(protocol);
1198 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1199
1adaa02b
TB
1200 sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
1201 sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1202 sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange));
1203 sa2->sadb_x_sa2_reqid = reqid;
1204 PFKEY_EXT_ADD(msg, sa2);
7daf5226 1205
f55a7a76
TB
1206 add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
1207 add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
7daf5226 1208
1adaa02b
TB
1209 range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg);
1210 range->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
1211 range->sadb_spirange_len = PFKEY_LEN(sizeof(struct sadb_spirange));
1212 range->sadb_spirange_min = 0xc0000000;
1213 range->sadb_spirange_max = 0xcFFFFFFF;
1214 PFKEY_EXT_ADD(msg, range);
7daf5226 1215
1adaa02b
TB
1216 if (pfkey_send(this, msg, &out, &len) == SUCCESS)
1217 {
1218 if (out->sadb_msg_errno)
1219 {
1220 DBG1(DBG_KNL, "allocating SPI failed: %s (%d)",
1221 strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1222 }
1223 else if (parse_pfkey_message(out, &response) == SUCCESS)
1224 {
1225 received_spi = response.sa->sadb_sa_spi;
1226 }
d24a74c5 1227 free(out);
1adaa02b 1228 }
7daf5226 1229
1adaa02b
TB
1230 if (received_spi == 0)
1231 {
1232 return FAILED;
1233 }
7daf5226 1234
1adaa02b
TB
1235 *spi = received_spi;
1236 return SUCCESS;
1237}
1238
44791b75
MW
1239METHOD(kernel_ipsec_t, get_cpi, status_t,
1240 private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
1241 u_int32_t reqid, u_int16_t *cpi)
1adaa02b
TB
1242{
1243 return FAILED;
1244}
1245
44791b75
MW
1246METHOD(kernel_ipsec_t, add_sa, status_t,
1247 private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
ee26c537
AS
1248 protocol_id_t protocol, u_int32_t reqid, mark_t mark,
1249 lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
1250 u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
1251 u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
1252 traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
1adaa02b
TB
1253{
1254 unsigned char request[PFKEY_BUFFER_SIZE];
1255 struct sadb_msg *msg, *out;
1256 struct sadb_sa *sa;
1257 struct sadb_x_sa2 *sa2;
1adaa02b
TB
1258 struct sadb_lifetime *lft;
1259 struct sadb_key *key;
1260 size_t len;
7daf5226 1261
1adaa02b 1262 memset(&request, 0, sizeof(request));
7daf5226 1263
ef6d339c 1264 DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", ntohl(spi), reqid);
7daf5226 1265
1adaa02b
TB
1266 msg = (struct sadb_msg*)request;
1267 msg->sadb_msg_version = PF_KEY_V2;
ea625fab 1268 msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD;
1adaa02b
TB
1269 msg->sadb_msg_satype = proto_ike2satype(protocol);
1270 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
e20bd8b6
TB
1271
1272#ifdef __APPLE__
1273 if (encap)
1274 {
1275 struct sadb_sa_2 *sa_2;
1276 sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg);
1277 sa_2->sadb_sa_natt_port = dst->get_port(dst);
1278 sa = &sa_2->sa;
1279 sa->sadb_sa_flags |= SADB_X_EXT_NATT;
1280 len = sizeof(struct sadb_sa_2);
1281 }
1282 else
1283#endif
1284 {
1285 sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
1286 len = sizeof(struct sadb_sa);
1287 }
1adaa02b 1288 sa->sadb_sa_exttype = SADB_EXT_SA;
e20bd8b6 1289 sa->sadb_sa_len = PFKEY_LEN(len);
1adaa02b
TB
1290 sa->sadb_sa_spi = spi;
1291 sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32;
e517b4b1
MW
1292 sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg);
1293 sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg);
1adaa02b 1294 PFKEY_EXT_ADD(msg, sa);
7daf5226 1295
1adaa02b
TB
1296 sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
1297 sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1298 sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange));
1299 sa2->sadb_x_sa2_mode = mode2kernel(mode);
1300 sa2->sadb_x_sa2_reqid = reqid;
1301 PFKEY_EXT_ADD(msg, sa2);
7daf5226 1302
f55a7a76
TB
1303 add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
1304 add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
7daf5226 1305
1adaa02b
TB
1306 lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg);
1307 lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1308 lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime));
e75f4237
TB
1309 lft->sadb_lifetime_allocations = lifetime->packets.rekey;
1310 lft->sadb_lifetime_bytes = lifetime->bytes.rekey;
1311 lft->sadb_lifetime_addtime = lifetime->time.rekey;
1087b9ce 1312 lft->sadb_lifetime_usetime = 0; /* we only use addtime */
1adaa02b 1313 PFKEY_EXT_ADD(msg, lft);
7daf5226 1314
1adaa02b
TB
1315 lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg);
1316 lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1317 lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime));
e75f4237
TB
1318 lft->sadb_lifetime_allocations = lifetime->packets.life;
1319 lft->sadb_lifetime_bytes = lifetime->bytes.life;
1320 lft->sadb_lifetime_addtime = lifetime->time.life;
1087b9ce 1321 lft->sadb_lifetime_usetime = 0; /* we only use addtime */
1adaa02b 1322 PFKEY_EXT_ADD(msg, lft);
7daf5226 1323
1adaa02b
TB
1324 if (enc_alg != ENCR_UNDEFINED)
1325 {
1326 if (!sa->sadb_sa_encrypt)
1327 {
1328 DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
e517b4b1 1329 encryption_algorithm_names, enc_alg);
1adaa02b
TB
1330 return FAILED;
1331 }
1332 DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
e517b4b1 1333 encryption_algorithm_names, enc_alg, enc_key.len * 8);
7daf5226 1334
1adaa02b
TB
1335 key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg);
1336 key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
e517b4b1
MW
1337 key->sadb_key_bits = enc_key.len * 8;
1338 key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len);
1339 memcpy(key + 1, enc_key.ptr, enc_key.len);
7daf5226 1340
1adaa02b
TB
1341 PFKEY_EXT_ADD(msg, key);
1342 }
7daf5226 1343
1adaa02b
TB
1344 if (int_alg != AUTH_UNDEFINED)
1345 {
1346 if (!sa->sadb_sa_auth)
1347 {
1348 DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
1349 integrity_algorithm_names, int_alg);
1350 return FAILED;
1351 }
1352 DBG2(DBG_KNL, " using integrity algorithm %N with key size %d",
e517b4b1 1353 integrity_algorithm_names, int_alg, int_key.len * 8);
7daf5226 1354
1adaa02b
TB
1355 key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg);
1356 key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
e517b4b1
MW
1357 key->sadb_key_bits = int_key.len * 8;
1358 key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len);
1359 memcpy(key + 1, int_key.ptr, int_key.len);
7daf5226 1360
1adaa02b
TB
1361 PFKEY_EXT_ADD(msg, key);
1362 }
7daf5226 1363
1adaa02b
TB
1364 if (ipcomp != IPCOMP_NONE)
1365 {
1366 /*TODO*/
1367 }
d24a74c5
TB
1368
1369#ifdef HAVE_NATT
1adaa02b
TB
1370 if (encap)
1371 {
1372 add_encap_ext(msg, src, dst);
1373 }
d24a74c5 1374#endif /*HAVE_NATT*/
7daf5226 1375
1adaa02b
TB
1376 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1377 {
1378 DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
1379 return FAILED;
1380 }
1381 else if (out->sadb_msg_errno)
1382 {
1383 DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x: %s (%d)",
1384 ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1385 free(out);
1386 return FAILED;
1387 }
7daf5226 1388
1adaa02b
TB
1389 free(out);
1390 return SUCCESS;
1391}
1392
44791b75
MW
1393METHOD(kernel_ipsec_t, update_sa, status_t,
1394 private_kernel_pfkey_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
1395 u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
ee26c537 1396 bool encap, bool new_encap, mark_t mark)
1adaa02b
TB
1397{
1398 unsigned char request[PFKEY_BUFFER_SIZE];
1399 struct sadb_msg *msg, *out;
1400 struct sadb_sa *sa;
1adaa02b
TB
1401 pfkey_msg_t response;
1402 size_t len;
7daf5226 1403
ea625fab
TB
1404 /* we can't update the SA if any of the ip addresses have changed.
1405 * that's because we can't use SADB_UPDATE and by deleting and readding the
1406 * SA the sequence numbers would get lost */
1407 if (!src->ip_equals(src, new_src) ||
1408 !dst->ip_equals(dst, new_dst))
1409 {
1410 DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address changes"
1411 " are not supported", ntohl(spi));
1412 return NOT_SUPPORTED;
1413 }
7daf5226 1414
1adaa02b 1415 memset(&request, 0, sizeof(request));
7daf5226 1416
1adaa02b 1417 DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
7daf5226 1418
1adaa02b
TB
1419 msg = (struct sadb_msg*)request;
1420 msg->sadb_msg_version = PF_KEY_V2;
1421 msg->sadb_msg_type = SADB_GET;
1422 msg->sadb_msg_satype = proto_ike2satype(protocol);
1423 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1424
1adaa02b
TB
1425 sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
1426 sa->sadb_sa_exttype = SADB_EXT_SA;
1427 sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
1428 sa->sadb_sa_spi = spi;
1429 PFKEY_EXT_ADD(msg, sa);
7daf5226 1430
1adaa02b 1431 /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though
f55a7a76
TB
1432 * it is not used for anything. */
1433 add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC);
1434 add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
7daf5226 1435
1adaa02b
TB
1436 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1437 {
1438 DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x",
1439 ntohl(spi));
1440 return FAILED;
1441 }
1442 else if (out->sadb_msg_errno)
1443 {
1444 DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)",
1445 ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1446 free(out);
1447 return FAILED;
1448 }
1449 else if (parse_pfkey_message(out, &response) != SUCCESS)
1450 {
1451 DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: parsing response "
1452 "from kernel failed", ntohl(spi));
1453 free(out);
1454 return FAILED;
1455 }
7daf5226 1456
1adaa02b
TB
1457 DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
1458 ntohl(spi), src, dst, new_src, new_dst);
7daf5226 1459
1adaa02b 1460 memset(&request, 0, sizeof(request));
7daf5226 1461
1adaa02b
TB
1462 msg = (struct sadb_msg*)request;
1463 msg->sadb_msg_version = PF_KEY_V2;
ea625fab 1464 msg->sadb_msg_type = SADB_UPDATE;
1adaa02b
TB
1465 msg->sadb_msg_satype = proto_ike2satype(protocol);
1466 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1467
e20bd8b6
TB
1468#ifdef __APPLE__
1469 {
1470 struct sadb_sa_2 *sa_2;
1471 sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg);
1472 sa_2->sa.sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa_2));
1473 memcpy(&sa_2->sa, response.sa, sizeof(struct sadb_sa));
1474 if (encap)
1475 {
1476 sa_2->sadb_sa_natt_port = new_dst->get_port(new_dst);
1477 sa_2->sa.sadb_sa_flags |= SADB_X_EXT_NATT;
1478 }
1479 }
1480#else
1adaa02b 1481 PFKEY_EXT_COPY(msg, response.sa);
e20bd8b6 1482#endif
1adaa02b 1483 PFKEY_EXT_COPY(msg, response.x_sa2);
7daf5226 1484
ea625fab
TB
1485 PFKEY_EXT_COPY(msg, response.src);
1486 PFKEY_EXT_COPY(msg, response.dst);
7daf5226 1487
1adaa02b
TB
1488 PFKEY_EXT_COPY(msg, response.lft_soft);
1489 PFKEY_EXT_COPY(msg, response.lft_hard);
7daf5226 1490
1adaa02b
TB
1491 if (response.key_encr)
1492 {
1493 PFKEY_EXT_COPY(msg, response.key_encr);
1494 }
7daf5226 1495
1adaa02b
TB
1496 if (response.key_auth)
1497 {
1498 PFKEY_EXT_COPY(msg, response.key_auth);
1499 }
7daf5226 1500
d24a74c5 1501#ifdef HAVE_NATT
8d50c198 1502 if (new_encap)
1adaa02b
TB
1503 {
1504 add_encap_ext(msg, new_src, new_dst);
1505 }
d24a74c5 1506#endif /*HAVE_NATT*/
7daf5226 1507
1adaa02b 1508 free(out);
7daf5226 1509
1adaa02b
TB
1510 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1511 {
1512 DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi));
1513 return FAILED;
1514 }
1515 else if (out->sadb_msg_errno)
1516 {
1517 DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: %s (%d)",
1518 ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1519 free(out);
1520 return FAILED;
1521 }
1522 free(out);
7daf5226 1523
1adaa02b
TB
1524 return SUCCESS;
1525}
1526
44791b75
MW
1527METHOD(kernel_ipsec_t, query_sa, status_t,
1528 private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
ee26c537 1529 u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
2ad51539 1530{
f35f229f
AS
1531 unsigned char request[PFKEY_BUFFER_SIZE];
1532 struct sadb_msg *msg, *out;
1533 struct sadb_sa *sa;
1534 pfkey_msg_t response;
1535 size_t len;
7daf5226 1536
f35f229f 1537 memset(&request, 0, sizeof(request));
7daf5226 1538
f35f229f 1539 DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
7daf5226 1540
f35f229f
AS
1541 msg = (struct sadb_msg*)request;
1542 msg->sadb_msg_version = PF_KEY_V2;
1543 msg->sadb_msg_type = SADB_GET;
1544 msg->sadb_msg_satype = proto_ike2satype(protocol);
1545 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1546
f35f229f
AS
1547 sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
1548 sa->sadb_sa_exttype = SADB_EXT_SA;
1549 sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
1550 sa->sadb_sa_spi = spi;
1551 PFKEY_EXT_ADD(msg, sa);
7daf5226 1552
f35f229f
AS
1553 /* the Linux Kernel doesn't care for the src address, but other systems do
1554 * (e.g. FreeBSD)
1555 */
1556 add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
1557 add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
7daf5226 1558
f35f229f
AS
1559 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1560 {
1561 DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi));
1562 return FAILED;
1563 }
1564 else if (out->sadb_msg_errno)
1565 {
1566 DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)",
1567 ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1568 free(out);
1569 return FAILED;
1570 }
1571 else if (parse_pfkey_message(out, &response) != SUCCESS)
1572 {
1573 DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi));
1574 free(out);
1575 return FAILED;
1576 }
1577 *bytes = response.lft_current->sadb_lifetime_bytes;
1578
1579 free(out);
1580 return SUCCESS;
2ad51539
AS
1581}
1582
44791b75
MW
1583METHOD(kernel_ipsec_t, del_sa, status_t,
1584 private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
ee26c537 1585 u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
1adaa02b
TB
1586{
1587 unsigned char request[PFKEY_BUFFER_SIZE];
1588 struct sadb_msg *msg, *out;
1589 struct sadb_sa *sa;
1adaa02b 1590 size_t len;
7daf5226 1591
1adaa02b 1592 memset(&request, 0, sizeof(request));
7daf5226 1593
1adaa02b 1594 DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
7daf5226 1595
1adaa02b
TB
1596 msg = (struct sadb_msg*)request;
1597 msg->sadb_msg_version = PF_KEY_V2;
1598 msg->sadb_msg_type = SADB_DELETE;
1599 msg->sadb_msg_satype = proto_ike2satype(protocol);
1600 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1601
1adaa02b
TB
1602 sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
1603 sa->sadb_sa_exttype = SADB_EXT_SA;
1604 sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
1605 sa->sadb_sa_spi = spi;
1606 PFKEY_EXT_ADD(msg, sa);
7daf5226 1607
f35f229f
AS
1608 /* the Linux Kernel doesn't care for the src address, but other systems do
1609 * (e.g. FreeBSD)
1610 */
d24a74c5 1611 add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
f55a7a76 1612 add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
7daf5226 1613
1adaa02b
TB
1614 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1615 {
1616 DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
1617 return FAILED;
1618 }
1619 else if (out->sadb_msg_errno)
1620 {
1621 DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x: %s (%d)",
1622 ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1623 free(out);
1624 return FAILED;
1625 }
7daf5226 1626
1adaa02b
TB
1627 DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
1628 free(out);
1629 return SUCCESS;
1630}
1631
44791b75
MW
1632METHOD(kernel_ipsec_t, add_policy, status_t,
1633 private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
1634 traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
1635 policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
ee26c537
AS
1636 u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
1637 u_int16_t cpi, bool routed)
1adaa02b
TB
1638{
1639 unsigned char request[PFKEY_BUFFER_SIZE];
1640 struct sadb_msg *msg, *out;
1641 struct sadb_x_policy *pol;
1adaa02b
TB
1642 struct sadb_x_ipsecrequest *req;
1643 policy_entry_t *policy, *found = NULL;
1644 pfkey_msg_t response;
1645 size_t len;
7daf5226 1646
eab05274
TB
1647 if (dir2kernel(direction) == IPSEC_DIR_INVALID)
1648 {
1649 /* FWD policies are not supported on all platforms */
1650 return SUCCESS;
1651 }
7daf5226 1652
1adaa02b
TB
1653 /* create a policy */
1654 policy = create_policy_entry(src_ts, dst_ts, direction, reqid);
7daf5226 1655
1adaa02b 1656 /* find a matching policy */
3ac5a0db 1657 this->mutex->lock(this->mutex);
1adaa02b
TB
1658 if (this->policies->find_first(this->policies,
1659 (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS)
1660 {
1661 /* use existing policy */
1662 found->refcount++;
1663 DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
1664 "refcount", src_ts, dst_ts,
1665 policy_dir_names, direction);
1666 policy_entry_destroy(policy);
1667 policy = found;
1668 }
1669 else
1670 {
1671 /* apply the new one, if we have no such policy */
1672 this->policies->insert_last(this->policies, policy);
1673 policy->refcount = 1;
1674 }
7daf5226 1675
1adaa02b 1676 memset(&request, 0, sizeof(request));
7daf5226 1677
1adaa02b
TB
1678 DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts,
1679 policy_dir_names, direction);
7daf5226 1680
1adaa02b
TB
1681 msg = (struct sadb_msg*)request;
1682 msg->sadb_msg_version = PF_KEY_V2;
1683 msg->sadb_msg_type = found ? SADB_X_SPDUPDATE : SADB_X_SPDADD;
1684 msg->sadb_msg_satype = 0;
1685 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1686
1adaa02b
TB
1687 pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg);
1688 pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1689 pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
1690 pol->sadb_x_policy_id = 0;
1691 pol->sadb_x_policy_dir = dir2kernel(direction);
d24a74c5
TB
1692 pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
1693#ifdef HAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY
1adaa02b 1694 /* calculate priority based on source selector size, small size = high prio */
ea625fab 1695 pol->sadb_x_policy_priority = routed ? PRIO_LOW : PRIO_HIGH;
1adaa02b
TB
1696 pol->sadb_x_policy_priority -= policy->src.mask * 10;
1697 pol->sadb_x_policy_priority -= policy->src.proto != IPSEC_PROTO_ANY ? 2 : 0;
1698 pol->sadb_x_policy_priority -= policy->src.net->get_port(policy->src.net) ? 1 : 0;
d24a74c5 1699#endif
7daf5226 1700
1adaa02b
TB
1701 /* one or more sadb_x_ipsecrequest extensions are added to the sadb_x_policy extension */
1702 req = (struct sadb_x_ipsecrequest*)(pol + 1);
1703 req->sadb_x_ipsecrequest_proto = proto_ike2ip(protocol);
1704 /* !!! the length of this struct MUST be in octets instead of 64 bit words */
1705 req->sadb_x_ipsecrequest_len = sizeof(struct sadb_x_ipsecrequest);
1706 req->sadb_x_ipsecrequest_mode = mode2kernel(mode);
1707 req->sadb_x_ipsecrequest_reqid = reqid;
1708 req->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
1709 if (mode == MODE_TUNNEL)
1710 {
668e84d9
TB
1711 len = hostcpy(req + 1, src);
1712 req->sadb_x_ipsecrequest_len += len;
1713 len = hostcpy((char*)(req + 1) + len, dst);
1714 req->sadb_x_ipsecrequest_len += len;
1adaa02b 1715 }
7daf5226 1716
1adaa02b
TB
1717 pol->sadb_x_policy_len += PFKEY_LEN(req->sadb_x_ipsecrequest_len);
1718 PFKEY_EXT_ADD(msg, pol);
7daf5226 1719
f55a7a76
TB
1720 add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
1721 policy->src.mask);
1722 add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto,
1723 policy->dst.mask);
7daf5226 1724
bfca7aa5
TB
1725#ifdef __FreeBSD__
1726 { /* on FreeBSD a lifetime has to be defined to be able to later query
1727 * the current use time. */
1728 struct sadb_lifetime *lft;
1729 lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg);
1730 lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1731 lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime));
79ff6141 1732 lft->sadb_lifetime_addtime = LONG_MAX;
bfca7aa5
TB
1733 PFKEY_EXT_ADD(msg, lft);
1734 }
1735#endif
7daf5226 1736
3ac5a0db 1737 this->mutex->unlock(this->mutex);
7daf5226 1738
1adaa02b
TB
1739 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1740 {
1741 DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts,
1742 policy_dir_names, direction);
1743 return FAILED;
1744 }
1745 else if (out->sadb_msg_errno)
1746 {
1747 DBG1(DBG_KNL, "unable to add policy %R === %R %N: %s (%d)", src_ts, dst_ts,
1748 policy_dir_names, direction,
1749 strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1750 free(out);
1751 return FAILED;
1752 }
1753 else if (parse_pfkey_message(out, &response) != SUCCESS)
1754 {
1755 DBG1(DBG_KNL, "unable to add policy %R === %R %N: parsing response "
1756 "from kernel failed", src_ts, dst_ts, policy_dir_names, direction);
1757 free(out);
1758 return FAILED;
1759 }
7daf5226 1760
3ac5a0db 1761 this->mutex->lock(this->mutex);
7daf5226 1762
1adaa02b
TB
1763 /* we try to find the policy again and update the kernel index */
1764 if (this->policies->find_last(this->policies, NULL, (void**)&policy) != SUCCESS)
1765 {
1766 DBG2(DBG_KNL, "unable to update index, the policy %R === %R %N is "
1767 "already gone, ignoring", src_ts, dst_ts, policy_dir_names, direction);
3ac5a0db 1768 this->mutex->unlock(this->mutex);
1adaa02b
TB
1769 free(out);
1770 return SUCCESS;
1771 }
1772 policy->index = response.x_policy->sadb_x_policy_id;
1773 free(out);
7daf5226 1774
1adaa02b
TB
1775 /* install a route, if:
1776 * - we are NOT updating a policy
1777 * - this is a forward policy (to just get one for each child)
1778 * - we are in tunnel mode
1779 * - we are not using IPv6 (does not work correctly yet!)
1780 * - routing is not disabled via strongswan.conf
1781 */
1782 if (policy->route == NULL && direction == POLICY_FWD &&
1783 mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 &&
1784 this->install_routes)
1785 {
1786 route_entry_t *route = malloc_thing(route_entry_t);
7daf5226 1787
1adaa02b
TB
1788 if (charon->kernel_interface->get_address_by_ts(charon->kernel_interface,
1789 dst_ts, &route->src_ip) == SUCCESS)
1790 {
1791 /* get the nexthop to src (src as we are in POLICY_FWD).*/
1792 route->gateway = charon->kernel_interface->get_nexthop(
1793 charon->kernel_interface, src);
1794 route->if_name = charon->kernel_interface->get_interface(
1795 charon->kernel_interface, dst);
1796 route->dst_net = chunk_clone(policy->src.net->get_address(policy->src.net));
1797 route->prefixlen = policy->src.mask;
7daf5226 1798
9eb7f46b 1799 if (route->if_name)
1adaa02b 1800 {
9eb7f46b
TB
1801 switch (charon->kernel_interface->add_route(
1802 charon->kernel_interface, route->dst_net,
1803 route->prefixlen, route->gateway,
1804 route->src_ip, route->if_name))
1805 {
1806 default:
1807 DBG1(DBG_KNL, "unable to install source route for %H",
1808 route->src_ip);
1809 /* FALL */
1810 case ALREADY_DONE:
1811 /* route exists, do not uninstall */
1812 route_entry_destroy(route);
1813 break;
1814 case SUCCESS:
1815 /* cache the installed route */
1816 policy->route = route;
1817 break;
1818 }
1819 }
1820 else
1821 {
1822 route_entry_destroy(route);
1adaa02b
TB
1823 }
1824 }
1825 else
1826 {
1827 free(route);
1828 }
d24a74c5 1829 }
7daf5226 1830
d24a74c5 1831 this->mutex->unlock(this->mutex);
7daf5226 1832
1adaa02b
TB
1833 return SUCCESS;
1834}
1835
44791b75
MW
1836METHOD(kernel_ipsec_t, query_policy, status_t,
1837 private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
ee26c537
AS
1838 traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
1839 u_int32_t *use_time)
1adaa02b
TB
1840{
1841 unsigned char request[PFKEY_BUFFER_SIZE];
1842 struct sadb_msg *msg, *out;
1843 struct sadb_x_policy *pol;
1adaa02b
TB
1844 policy_entry_t *policy, *found = NULL;
1845 pfkey_msg_t response;
1846 size_t len;
7daf5226 1847
eab05274
TB
1848 if (dir2kernel(direction) == IPSEC_DIR_INVALID)
1849 {
1850 /* FWD policies are not supported on all platforms */
1851 return NOT_FOUND;
1852 }
7daf5226 1853
1adaa02b
TB
1854 DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
1855 policy_dir_names, direction);
1856
1857 /* create a policy */
1858 policy = create_policy_entry(src_ts, dst_ts, direction, 0);
7daf5226 1859
1adaa02b 1860 /* find a matching policy */
3ac5a0db 1861 this->mutex->lock(this->mutex);
1adaa02b
TB
1862 if (this->policies->find_first(this->policies,
1863 (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS)
1864 {
1865 DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", src_ts,
1866 dst_ts, policy_dir_names, direction);
1867 policy_entry_destroy(policy);
3ac5a0db 1868 this->mutex->unlock(this->mutex);
1adaa02b
TB
1869 return NOT_FOUND;
1870 }
1871 policy_entry_destroy(policy);
1872 policy = found;
7daf5226 1873
1adaa02b 1874 memset(&request, 0, sizeof(request));
7daf5226 1875
1adaa02b
TB
1876 msg = (struct sadb_msg*)request;
1877 msg->sadb_msg_version = PF_KEY_V2;
1878 msg->sadb_msg_type = SADB_X_SPDGET;
1879 msg->sadb_msg_satype = 0;
1880 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1881
1adaa02b
TB
1882 pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg);
1883 pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1884 pol->sadb_x_policy_id = policy->index;
1885 pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
1886 pol->sadb_x_policy_dir = dir2kernel(direction);
1887 pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
1888 PFKEY_EXT_ADD(msg, pol);
7daf5226 1889
f55a7a76
TB
1890 add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
1891 policy->src.mask);
1892 add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto,
1893 policy->dst.mask);
7daf5226 1894
3ac5a0db 1895 this->mutex->unlock(this->mutex);
7daf5226 1896
1adaa02b
TB
1897 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
1898 {
1899 DBG1(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts,
1900 policy_dir_names, direction);
1901 return FAILED;
1902 }
1903 else if (out->sadb_msg_errno)
1904 {
1905 DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts,
1906 dst_ts, policy_dir_names, direction,
1907 strerror(out->sadb_msg_errno), out->sadb_msg_errno);
1908 free(out);
1909 return FAILED;
1910 }
1911 else if (parse_pfkey_message(out, &response) != SUCCESS)
1912 {
1913 DBG1(DBG_KNL, "unable to query policy %R === %R %N: parsing response "
1914 "from kernel failed", src_ts, dst_ts, policy_dir_names, direction);
1915 free(out);
1916 return FAILED;
1917 }
524f9ac4
TB
1918 else if (response.lft_current == NULL)
1919 {
1920 DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no "
1921 "use time", src_ts, dst_ts, policy_dir_names, direction);
1922 free(out);
1923 return FAILED;
1924 }
6180a558
MW
1925 /* we need the monotonic time, but the kernel returns system time. */
1926 if (response.lft_current->sadb_lifetime_usetime)
1927 {
1928 *use_time = time_monotonic(NULL) -
1929 (time(NULL) - response.lft_current->sadb_lifetime_usetime);
1930 }
1931 else
1932 {
1933 *use_time = 0;
1934 }
1adaa02b 1935 free(out);
7daf5226 1936
1adaa02b
TB
1937 return SUCCESS;
1938}
1939
44791b75
MW
1940METHOD(kernel_ipsec_t, del_policy, status_t,
1941 private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
ee26c537
AS
1942 traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
1943 bool unrouted)
1adaa02b
TB
1944{
1945 unsigned char request[PFKEY_BUFFER_SIZE];
1946 struct sadb_msg *msg, *out;
1947 struct sadb_x_policy *pol;
1adaa02b
TB
1948 policy_entry_t *policy, *found = NULL;
1949 route_entry_t *route;
1950 size_t len;
7daf5226 1951
eab05274
TB
1952 if (dir2kernel(direction) == IPSEC_DIR_INVALID)
1953 {
1954 /* FWD policies are not supported on all platforms */
1955 return SUCCESS;
1956 }
7daf5226 1957
1adaa02b
TB
1958 DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts,
1959 policy_dir_names, direction);
7daf5226 1960
1adaa02b
TB
1961 /* create a policy */
1962 policy = create_policy_entry(src_ts, dst_ts, direction, 0);
7daf5226 1963
1adaa02b 1964 /* find a matching policy */
3ac5a0db 1965 this->mutex->lock(this->mutex);
1adaa02b
TB
1966 if (this->policies->find_first(this->policies,
1967 (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS)
1968 {
1969 if (--found->refcount > 0)
1970 {
1971 /* is used by more SAs, keep in kernel */
d24a74c5 1972 DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
1adaa02b 1973 policy_entry_destroy(policy);
3ac5a0db 1974 this->mutex->unlock(this->mutex);
1adaa02b
TB
1975 return SUCCESS;
1976 }
1977 /* remove if last reference */
1978 this->policies->remove(this->policies, found, NULL);
1979 policy_entry_destroy(policy);
1980 policy = found;
1981 }
1982 else
1983 {
1984 DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts,
1985 dst_ts, policy_dir_names, direction);
1986 policy_entry_destroy(policy);
3ac5a0db 1987 this->mutex->unlock(this->mutex);
1adaa02b
TB
1988 return NOT_FOUND;
1989 }
3ac5a0db 1990 this->mutex->unlock(this->mutex);
7daf5226 1991
1adaa02b 1992 memset(&request, 0, sizeof(request));
7daf5226 1993
1adaa02b
TB
1994 msg = (struct sadb_msg*)request;
1995 msg->sadb_msg_version = PF_KEY_V2;
1996 msg->sadb_msg_type = SADB_X_SPDDELETE;
1997 msg->sadb_msg_satype = 0;
1998 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 1999
1adaa02b
TB
2000 pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg);
2001 pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2002 pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
2003 pol->sadb_x_policy_dir = dir2kernel(direction);
2004 pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2005 PFKEY_EXT_ADD(msg, pol);
7daf5226 2006
f55a7a76
TB
2007 add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
2008 policy->src.mask);
2009 add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto,
2010 policy->dst.mask);
7daf5226 2011
1adaa02b
TB
2012 route = policy->route;
2013 policy->route = NULL;
2014 policy_entry_destroy(policy);
7daf5226 2015
1adaa02b
TB
2016 if (pfkey_send(this, msg, &out, &len) != SUCCESS)
2017 {
2018 DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts,
2019 policy_dir_names, direction);
2020 return FAILED;
2021 }
2022 else if (out->sadb_msg_errno)
2023 {
2024 DBG1(DBG_KNL, "unable to delete policy %R === %R %N: %s (%d)", src_ts,
2025 dst_ts, policy_dir_names, direction,
2026 strerror(out->sadb_msg_errno), out->sadb_msg_errno);
2027 free(out);
2028 return FAILED;
2029 }
2030 free(out);
7daf5226 2031
1adaa02b
TB
2032 if (route)
2033 {
2034 if (charon->kernel_interface->del_route(charon->kernel_interface,
2035 route->dst_net, route->prefixlen, route->gateway,
2036 route->src_ip, route->if_name) != SUCCESS)
2037 {
2038 DBG1(DBG_KNL, "error uninstalling route installed with "
2039 "policy %R === %R %N", src_ts, dst_ts,
2040 policy_dir_names, direction);
d24a74c5 2041 }
1adaa02b
TB
2042 route_entry_destroy(route);
2043 }
7daf5226 2044
1adaa02b
TB
2045 return SUCCESS;
2046}
2047
2048/**
2049 * Register a socket for AQUIRE/EXPIRE messages
2050 */
44791b75
MW
2051static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this,
2052 u_int8_t satype)
1adaa02b
TB
2053{
2054 unsigned char request[PFKEY_BUFFER_SIZE];
2055 struct sadb_msg *msg, *out;
1adaa02b 2056 size_t len;
7daf5226 2057
1adaa02b 2058 memset(&request, 0, sizeof(request));
7daf5226 2059
1adaa02b
TB
2060 msg = (struct sadb_msg*)request;
2061 msg->sadb_msg_version = PF_KEY_V2;
2062 msg->sadb_msg_type = SADB_REGISTER;
2063 msg->sadb_msg_satype = satype;
2064 msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
7daf5226 2065
1adaa02b
TB
2066 if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS)
2067 {
2068 DBG1(DBG_KNL, "unable to register PF_KEY socket");
2069 return FAILED;
2070 }
2071 else if (out->sadb_msg_errno)
2072 {
2073 DBG1(DBG_KNL, "unable to register PF_KEY socket: %s (%d)",
2074 strerror(out->sadb_msg_errno), out->sadb_msg_errno);
2075 free(out);
2076 return FAILED;
2077 }
2078 free(out);
2079 return SUCCESS;
2080}
2081
54f81859
MW
2082METHOD(kernel_ipsec_t, bypass_socket, bool,
2083 private_kernel_pfkey_ipsec_t *this, int fd, int family)
ea625fab 2084{
54f81859
MW
2085 struct sadb_x_policy policy;
2086 u_int sol, ipsec_policy;
7daf5226 2087
54f81859 2088 switch (family)
ea625fab 2089 {
54f81859 2090 case AF_INET:
ea625fab 2091 {
54f81859
MW
2092 sol = SOL_IP;
2093 ipsec_policy = IP_IPSEC_POLICY;
e7c27b4f 2094 break;
ea625fab 2095 }
54f81859 2096 case AF_INET6:
ea625fab 2097 {
54f81859
MW
2098 sol = SOL_IPV6;
2099 ipsec_policy = IPV6_IPSEC_POLICY;
e7c27b4f 2100 break;
ea625fab 2101 }
54f81859
MW
2102 default:
2103 return FALSE;
ea625fab 2104 }
54f81859
MW
2105
2106 memset(&policy, 0, sizeof(policy));
2107 policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
2108 policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2109 policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
2110
2111 policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
2112 if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
2113 {
2114 DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
2115 strerror(errno));
2116 return FALSE;
2117 }
2118 policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
2119 if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
2120 {
2121 DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
2122 strerror(errno));
2123 return FALSE;
2124 }
2125 return TRUE;
2126}
2127
2128METHOD(kernel_ipsec_t, destroy, void,
2129 private_kernel_pfkey_ipsec_t *this)
2130{
d6a27ec6
MW
2131 if (this->job)
2132 {
2133 this->job->cancel(this->job);
2134 }
2135 if (this->socket > 0)
2136 {
2137 close(this->socket);
2138 }
2139 if (this->socket_events > 0)
2140 {
2141 close(this->socket_events);
2142 }
54f81859
MW
2143 this->policies->destroy_function(this->policies, (void*)policy_entry_destroy);
2144 this->mutex->destroy(this->mutex);
2145 this->mutex_pfkey->destroy(this->mutex_pfkey);
2146 free(this);
ea625fab
TB
2147}
2148
1adaa02b
TB
2149/*
2150 * Described in header.
2151 */
2152kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
2153{
44791b75
MW
2154 private_kernel_pfkey_ipsec_t *this;
2155
2156 INIT(this,
2157 .public.interface = {
2158 .get_spi = _get_spi,
2159 .get_cpi = _get_cpi,
2160 .add_sa = _add_sa,
2161 .update_sa = _update_sa,
2162 .query_sa = _query_sa,
2163 .del_sa = _del_sa,
2164 .add_policy = _add_policy,
2165 .query_policy = _query_policy,
2166 .del_policy = _del_policy,
54f81859 2167 .bypass_socket = _bypass_socket,
44791b75
MW
2168 .destroy = _destroy,
2169 },
2170 .policies = linked_list_create(),
2171 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
2172 .mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT),
2173 .install_routes = lib->settings->get_bool(lib->settings,
2174 "charon.install_routes", TRUE),
2175 );
7daf5226 2176
1adaa02b
TB
2177 /* create a PF_KEY socket to communicate with the kernel */
2178 this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
2179 if (this->socket <= 0)
2180 {
d6a27ec6
MW
2181 DBG1(DBG_KNL, "unable to create PF_KEY socket");
2182 destroy(this);
2183 return NULL;
1adaa02b 2184 }
7daf5226 2185
1adaa02b
TB
2186 /* create a PF_KEY socket for ACQUIRE & EXPIRE */
2187 this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
2188 if (this->socket_events <= 0)
2189 {
d6a27ec6
MW
2190 DBG1(DBG_KNL, "unable to create PF_KEY event socket");
2191 destroy(this);
2192 return NULL;
1adaa02b 2193 }
7daf5226 2194
1adaa02b
TB
2195 /* register the event socket */
2196 if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
2197 register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
2198 {
d6a27ec6
MW
2199 DBG1(DBG_KNL, "unable to register PF_KEY event socket");
2200 destroy(this);
2201 return NULL;
1adaa02b 2202 }
7daf5226 2203
1adaa02b
TB
2204 this->job = callback_job_create((callback_job_cb_t)receive_events,
2205 this, NULL, NULL);
2206 charon->processor->queue_job(charon->processor, (job_t*)this->job);
7daf5226 2207
1adaa02b
TB
2208 return &this->public;
2209}
44791b75 2210