IPsec policy manager added
[strongswan.git] / src / libipsec / ipsec_policy_mgr.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "ipsec_policy_mgr.h"
19 #include "ipsec_policy.h"
20
21 #include <debug.h>
22 #include <library.h>
23 #include <ipsec/ipsec_types.h>
24 #include <selectors/traffic_selector.h>
25 #include <threading/rwlock.h>
26 #include <utils/host.h>
27 #include <utils/linked_list.h>
28
29 typedef struct private_ipsec_policy_mgr_t private_ipsec_policy_mgr_t;
30
31 /**
32 * Private additions to ipsec_policy_mgr_t.
33 */
34 struct private_ipsec_policy_mgr_t {
35
36 /**
37 * Public members of ipsec_policy_mgr_t.
38 */
39 ipsec_policy_mgr_t public;
40
41 /**
42 * Installed policies
43 */
44 linked_list_t *policies;
45
46 /**
47 * Lock to safely access policies
48 */
49 rwlock_t *lock;
50
51 };
52
53 static bool match_policy(ipsec_policy_t *policy, ipsec_policy_t *other_policy)
54 {
55 return policy->match(policy, other_policy->get_source_ts(other_policy),
56 other_policy->get_destination_ts(other_policy),
57 other_policy->get_direction(other_policy),
58 other_policy->get_reqid(other_policy),
59 (mark_t){ .value = 0, },
60 other_policy->get_priority(other_policy));
61 }
62
63 METHOD(ipsec_policy_mgr_t, add_policy, status_t,
64 private_ipsec_policy_mgr_t *this, host_t *src, host_t *dst,
65 traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
66 policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, mark_t mark,
67 policy_priority_t priority)
68 {
69 ipsec_policy_t *policy;
70
71 policy = ipsec_policy_create(src, dst, src_ts, dst_ts, direction, type, sa,
72 mark, priority);
73 this->lock->write_lock(this->lock);
74 if (this->policies->find_first(this->policies, (void*)match_policy,
75 NULL, policy) != SUCCESS)
76 {
77 this->policies->insert_last(this->policies, policy);
78 }
79 else
80 {
81 policy->destroy(policy);
82 }
83 this->lock->unlock(this->lock);
84 return SUCCESS;
85 }
86
87 METHOD(ipsec_policy_mgr_t, del_policy, status_t,
88 private_ipsec_policy_mgr_t *this, traffic_selector_t *src_ts,
89 traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
90 mark_t mark, policy_priority_t priority)
91 {
92 enumerator_t *enumerator;
93 ipsec_policy_t *current, *found = NULL;
94
95 this->lock->write_lock(this->lock);
96 enumerator = this->policies->create_enumerator(this->policies);
97 while (enumerator->enumerate(enumerator, (void**)&current))
98 {
99 if (current->match(current, src_ts, dst_ts, direction, reqid,
100 mark, priority))
101 {
102 this->policies->remove_at(this->policies, enumerator);
103 found = current;
104 break;
105 }
106 }
107 enumerator->destroy(enumerator);
108 this->lock->unlock(this->lock);
109 if (found)
110 {
111 found->destroy(found);
112 return SUCCESS;
113 }
114 return FAILED;
115 }
116
117 METHOD(ipsec_policy_mgr_t, flush_policies, status_t,
118 private_ipsec_policy_mgr_t *this)
119 {
120 ipsec_policy_t *policy;
121
122 DBG2(DBG_ESP, "flushing policies");
123
124 this->lock->write_lock(this->lock);
125 while (this->policies->remove_last(this->policies,
126 (void**)&policy) == SUCCESS)
127 {
128 policy->destroy(policy);
129 }
130 this->lock->unlock(this->lock);
131 return SUCCESS;
132 }
133
134 METHOD(ipsec_policy_mgr_t, destroy, void,
135 private_ipsec_policy_mgr_t *this)
136 {
137 flush_policies(this);
138 this->policies->destroy(this->policies);
139 this->lock->destroy(this->lock);
140 free(this);
141 }
142
143 /**
144 * Described in header.
145 */
146 ipsec_policy_mgr_t *ipsec_policy_mgr_create()
147 {
148 private_ipsec_policy_mgr_t *this;
149
150 INIT(this,
151 .public = {
152 .add_policy = _add_policy,
153 .del_policy = _del_policy,
154 .flush_policies = _flush_policies,
155 .destroy = _destroy,
156 },
157 .policies = linked_list_create(),
158 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
159 );
160
161 return &this->public;
162 }