/src/strongswan/src/libcharon/kernel/kernel_handler.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2010 Tobias Brunner |
3 | | * |
4 | | * Copyright (C) secunet Security Networks AG |
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. |
15 | | */ |
16 | | |
17 | | #include "kernel_handler.h" |
18 | | |
19 | | #include <daemon.h> |
20 | | #include <processing/jobs/acquire_job.h> |
21 | | #include <processing/jobs/delete_child_sa_job.h> |
22 | | #include <processing/jobs/migrate_job.h> |
23 | | #include <processing/jobs/rekey_child_sa_job.h> |
24 | | #include <processing/jobs/roam_job.h> |
25 | | #include <processing/jobs/update_sa_job.h> |
26 | | |
27 | | typedef struct private_kernel_handler_t private_kernel_handler_t; |
28 | | |
29 | | /** |
30 | | * Private data of a kernel_handler_t object. |
31 | | */ |
32 | | struct private_kernel_handler_t { |
33 | | |
34 | | /** |
35 | | * Public part of kernel_handler_t object. |
36 | | */ |
37 | | kernel_handler_t public; |
38 | | }; |
39 | | |
40 | | /** |
41 | | * convert an IP protocol identifier to the IKEv2 specific protocol identifier. |
42 | | */ |
43 | | static inline protocol_id_t proto_ip2ike(uint8_t protocol) |
44 | 0 | { |
45 | 0 | switch (protocol) |
46 | 0 | { |
47 | 0 | case IPPROTO_ESP: |
48 | 0 | return PROTO_ESP; |
49 | 0 | case IPPROTO_AH: |
50 | 0 | return PROTO_AH; |
51 | 0 | default: |
52 | 0 | return protocol; |
53 | 0 | } |
54 | 0 | } |
55 | | |
56 | | METHOD(kernel_listener_t, acquire, bool, |
57 | | private_kernel_handler_t *this, uint32_t reqid, kernel_acquire_data_t *data) |
58 | 0 | { |
59 | 0 | char lbuf[BUF_LEN] = "", cbuf[32] = "", sbuf[32] = ""; |
60 | |
|
61 | 0 | if (data->label) |
62 | 0 | { |
63 | 0 | snprintf(lbuf, sizeof(lbuf), ", label {%s}", |
64 | 0 | data->label->get_string(data->label)); |
65 | 0 | } |
66 | 0 | if (data->cpu != CPU_ID_MAX) |
67 | 0 | { |
68 | 0 | snprintf(cbuf, sizeof(cbuf), ", cpu {%u}", data->cpu); |
69 | 0 | } |
70 | 0 | if (data->seq) |
71 | 0 | { |
72 | 0 | snprintf(sbuf, sizeof(sbuf), ", seq {%u}", data->seq); |
73 | 0 | } |
74 | 0 | if (data->src && data->dst) |
75 | 0 | { |
76 | 0 | DBG1(DBG_KNL, "creating acquire job for policy %R === %R with " |
77 | 0 | "reqid {%u}%s%s%s", data->src, data->dst, reqid, lbuf, cbuf, sbuf); |
78 | 0 | } |
79 | 0 | else |
80 | 0 | { |
81 | 0 | DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}%s%s%s", |
82 | 0 | reqid, lbuf, cbuf, sbuf); |
83 | 0 | } |
84 | 0 | lib->processor->queue_job(lib->processor, |
85 | 0 | (job_t*)acquire_job_create(reqid, data)); |
86 | 0 | return TRUE; |
87 | 0 | } |
88 | | |
89 | | METHOD(kernel_listener_t, expire, bool, |
90 | | private_kernel_handler_t *this, uint8_t protocol, uint32_t spi, |
91 | | host_t *dst, bool hard) |
92 | 0 | { |
93 | 0 | protocol_id_t proto = proto_ip2ike(protocol); |
94 | |
|
95 | 0 | DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H", |
96 | 0 | hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst); |
97 | |
|
98 | 0 | if (hard) |
99 | 0 | { |
100 | 0 | lib->processor->queue_job(lib->processor, |
101 | 0 | (job_t*)delete_child_sa_job_create(proto, spi, dst, hard)); |
102 | 0 | } |
103 | 0 | else |
104 | 0 | { |
105 | 0 | lib->processor->queue_job(lib->processor, |
106 | 0 | (job_t*)rekey_child_sa_job_create(proto, spi, dst)); |
107 | 0 | } |
108 | 0 | return TRUE; |
109 | 0 | } |
110 | | |
111 | | METHOD(kernel_listener_t, mapping, bool, |
112 | | private_kernel_handler_t *this, uint8_t protocol, uint32_t spi, |
113 | | host_t *dst, host_t *remote) |
114 | 0 | { |
115 | 0 | protocol_id_t proto = proto_ip2ike(protocol); |
116 | |
|
117 | 0 | DBG1(DBG_KNL, "NAT mappings of CHILD_SA %N/0x%08x/%H changed to %#H, " |
118 | 0 | "queuing update job", protocol_id_names, proto, ntohl(spi), dst, |
119 | 0 | remote); |
120 | |
|
121 | 0 | lib->processor->queue_job(lib->processor, |
122 | 0 | (job_t*)update_sa_job_create(proto, spi, dst, remote)); |
123 | 0 | return TRUE; |
124 | 0 | } |
125 | | |
126 | | METHOD(kernel_listener_t, migrate, bool, |
127 | | private_kernel_handler_t *this, uint32_t reqid, |
128 | | traffic_selector_t *src_ts, traffic_selector_t *dst_ts, |
129 | | policy_dir_t direction, host_t *local, host_t *remote) |
130 | 0 | { |
131 | 0 | DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}", |
132 | 0 | src_ts, dst_ts, policy_dir_names, direction, reqid, local); |
133 | |
|
134 | 0 | lib->processor->queue_job(lib->processor, |
135 | 0 | (job_t*)migrate_job_create(reqid, src_ts, dst_ts, |
136 | 0 | direction, local, remote)); |
137 | 0 | return TRUE; |
138 | 0 | } |
139 | | |
140 | | METHOD(kernel_listener_t, roam, bool, |
141 | | private_kernel_handler_t *this, bool address) |
142 | 0 | { |
143 | 0 | DBG2(DBG_KNL, "creating roam job %s", |
144 | 0 | address ? "due to address/link change" : "due to route change"); |
145 | |
|
146 | 0 | lib->processor->queue_job(lib->processor, (job_t*)roam_job_create(address)); |
147 | 0 | return TRUE; |
148 | 0 | } |
149 | | |
150 | | METHOD(kernel_handler_t, destroy, void, |
151 | | private_kernel_handler_t *this) |
152 | 0 | { |
153 | 0 | charon->kernel->remove_listener(charon->kernel, &this->public.listener); |
154 | 0 | free(this); |
155 | 0 | } |
156 | | |
157 | | kernel_handler_t *kernel_handler_create() |
158 | 2 | { |
159 | 2 | private_kernel_handler_t *this; |
160 | | |
161 | 2 | INIT(this, |
162 | 2 | .public = { |
163 | 2 | .listener = { |
164 | 2 | .acquire = _acquire, |
165 | 2 | .expire = _expire, |
166 | 2 | .mapping = _mapping, |
167 | 2 | .migrate = _migrate, |
168 | 2 | .roam = _roam, |
169 | 2 | }, |
170 | 2 | .destroy = _destroy, |
171 | 2 | }, |
172 | 2 | ); |
173 | | |
174 | 2 | charon->kernel->add_listener(charon->kernel, &this->public.listener); |
175 | | |
176 | 2 | return &this->public; |
177 | 2 | } |