]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/charon-tkm/src/tkm/tkm_kernel_sad.c
Various stylistic fixes
[thirdparty/strongswan.git] / src / charon-tkm / src / tkm / tkm_kernel_sad.c
CommitLineData
1e13904f
AKR
1/*
2 * Copyright (C) 2012 Reto Buerki
3 * Copyright (C) 2012 Adrian-Ken Rueegsegger
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.
15 */
16
17#include <collections/linked_list.h>
18#include <threading/mutex.h>
19#include <utils/debug.h>
20
21#include "tkm_kernel_sad.h"
22
23typedef struct private_tkm_kernel_sad_t private_tkm_kernel_sad_t;
24
25/**
26 * Private data of tkm_kernel_sad.
27 */
28struct private_tkm_kernel_sad_t {
29
30 /**
31 * Public functions.
32 */
33 tkm_kernel_sad_t public;
34
35 /**
36 * Linked list of SAD entries.
37 */
38 linked_list_t *data;
39
40 /**
41 * Lock used to protect SA data.
42 */
43 mutex_t *mutex;
44
45};
46
47typedef struct sad_entry_t sad_entry_t;
48
49/**
50 * Data structure holding all information of an SAD entry.
51 */
52struct sad_entry_t {
53
54 /**
55 * ESA identifier.
56 */
57 esa_id_type esa_id;
58
59 /**
60 * Source address of CHILD SA.
61 */
62 host_t *src;
63
64 /**
65 * Destination address of CHILD SA.
66 */
67 host_t *dst;
68
69 /**
70 * SPI of CHILD SA.
71 */
72 u_int32_t spi;
73
74 /**
75 * Protocol of CHILD SA (ESP/AH).
76 */
77 u_int8_t proto;
78
79};
80
81/**
82 * Destroy an sad_entry_t object.
83 */
84static void sad_entry_destroy(sad_entry_t *entry)
85{
86 if (entry)
87 {
88 DESTROY_IF(entry->src);
89 DESTROY_IF(entry->dst);
90 free(entry);
91 }
92}
93
94/**
95 * Find a list entry with given src, dst, spi and proto values.
96 */
97static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
98 const host_t * const dst, const u_int32_t * const spi,
99 const u_int8_t * const proto)
100{
101 if (entry->src == NULL || entry->dst == NULL)
102 {
103 return FALSE;
104 }
105
106 return src->ip_equals(entry->src, (host_t *)src) &&
107 dst->ip_equals(entry->dst, (host_t *)dst) &&
108 entry->spi == *spi && entry->proto == *proto;
109}
110
111/**
112 * Compare two SAD entries for equality.
113 */
114static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
115{
116 if (left->src == NULL || left->dst == NULL || right->src == NULL ||
117 right->dst == NULL)
118 {
119 return FALSE;
120 }
121 return left->esa_id == right->esa_id &&
122 left->src->ip_equals(left->src, right->src) &&
123 left->dst->ip_equals(left->dst, right->dst) &&
124 left->spi == right->spi && left->proto == right->proto;
125}
126
127METHOD(tkm_kernel_sad_t, insert, bool,
128 private_tkm_kernel_sad_t * const this, const esa_id_type esa_id,
129 const host_t * const src, const host_t * const dst, const u_int32_t spi,
130 const u_int8_t proto)
131{
7cc6fa1a 132 status_t result;
1e13904f 133 sad_entry_t *new_entry;
7cc6fa1a 134
1e13904f
AKR
135 INIT(new_entry,
136 .esa_id = esa_id,
137 .src = (host_t *)src,
138 .dst = (host_t *)dst,
139 .spi = spi,
140 .proto = proto,
141 );
142
143 this->mutex->lock(this->mutex);
7cc6fa1a
AKR
144 result = this->data->find_first(this->data,
145 (linked_list_match_t)sad_entry_equal, NULL,
146 new_entry);
1e13904f
AKR
147 if (result == NOT_FOUND)
148 {
149 DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, src: %H, dst: %H, "
150 "spi: %x, proto: %u)", esa_id, src, dst, ntohl(spi), proto);
151 new_entry->src = src->clone((host_t *)src);
152 new_entry->dst = dst->clone((host_t *)dst);
153 this->data->insert_last(this->data, new_entry);
154 }
155 else
156 {
157 DBG1(DBG_KNL, "SAD entry with esa id %llu already exists!", esa_id);
158 free(new_entry);
159 }
160 this->mutex->unlock(this->mutex);
161 return result == NOT_FOUND;
162}
163
164METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
165 private_tkm_kernel_sad_t * const this, const host_t * const src,
166 const host_t * const dst, const u_int32_t spi, const u_int8_t proto)
167{
168 esa_id_type id = 0;
169 sad_entry_t *entry = NULL;
170
171 this->mutex->lock(this->mutex);
172 const status_t res = this->data->find_first(this->data,
173 (linked_list_match_t)sad_entry_match,
174 (void**)&entry, src, dst, &spi,
175 &proto);
176 if (res == SUCCESS && entry)
177 {
178 id = entry->esa_id;
179 DBG3(DBG_KNL, "getting ESA id of SAD entry (esa: %llu, src: %H, "
180 "dst: %H, spi: %x, proto: %u)", id, src, dst, ntohl(spi),
181 proto);
182 }
183 else
184 {
185 DBG3(DBG_KNL, "no SAD entry found");
186 }
187 this->mutex->unlock(this->mutex);
188 return id;
189}
190
191METHOD(tkm_kernel_sad_t, _remove, bool,
192 private_tkm_kernel_sad_t * const this, const esa_id_type esa_id)
193{
194 sad_entry_t *current;
195 bool removed = FALSE;
7cc6fa1a
AKR
196 enumerator_t *enumerator;
197
1e13904f 198 this->mutex->lock(this->mutex);
7cc6fa1a 199 enumerator = this->data->create_enumerator(this->data);
1e13904f
AKR
200 while (enumerator->enumerate(enumerator, (void **)&current))
201 {
202 if (current->esa_id == esa_id)
203 {
204 this->data->remove_at(this->data, enumerator);
205 sad_entry_destroy(current);
206 removed = TRUE;
207 break;
208 }
209 }
210 enumerator->destroy(enumerator);
211
212 if (removed)
213 {
214 DBG3(DBG_KNL, "removed SAD entry (esa: %llu)", esa_id);
215 }
216 else
217 {
218 DBG1(DBG_KNL, "no SAD entry with ESA id %llu found!", esa_id);
219 }
220 this->mutex->unlock(this->mutex);
221
222 return removed;
223}
224
225
226METHOD(tkm_kernel_sad_t, destroy, void,
227 private_tkm_kernel_sad_t *this)
228{
229 this->mutex->destroy(this->mutex);
230 this->data->destroy_function(this->data, (void*)sad_entry_destroy);
231 free(this);
232}
233
234/*
235 * see header file
236 */
237tkm_kernel_sad_t *tkm_kernel_sad_create()
238{
239 private_tkm_kernel_sad_t *this;
240
241 INIT(this,
242 .public = {
243 .insert = _insert,
244 .get_esa_id = _get_esa_id,
245 .remove = __remove,
246 .destroy = _destroy,
247 },
248 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
249 .data = linked_list_create(),
250 );
251
252 return &this->public;
253}