aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/xfrm6_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/xfrm6_state.c')
-rw-r--r--net/ipv6/xfrm6_state.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 9c95b9d3e110..e0b8f3c5caa2 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -156,12 +156,109 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto,
156 return x0; 156 return x0;
157} 157}
158 158
159static int
160__xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
161{
162 int i;
163 int j = 0;
164
165 /* Rule 1: select IPsec transport except AH */
166 for (i = 0; i < n; i++) {
167 if (src[i]->props.mode == XFRM_MODE_TRANSPORT &&
168 src[i]->id.proto != IPPROTO_AH) {
169 dst[j++] = src[i];
170 src[i] = NULL;
171 }
172 }
173 if (j == n)
174 goto end;
175
176 /* XXX: Rule 2: select MIPv6 RO or inbound trigger */
177
178 /* Rule 3: select IPsec transport AH */
179 for (i = 0; i < n; i++) {
180 if (src[i] &&
181 src[i]->props.mode == XFRM_MODE_TRANSPORT &&
182 src[i]->id.proto == IPPROTO_AH) {
183 dst[j++] = src[i];
184 src[i] = NULL;
185 }
186 }
187 if (j == n)
188 goto end;
189
190 /* Rule 4: select IPsec tunnel */
191 for (i = 0; i < n; i++) {
192 if (src[i] &&
193 src[i]->props.mode == XFRM_MODE_TUNNEL) {
194 dst[j++] = src[i];
195 src[i] = NULL;
196 }
197 }
198 if (likely(j == n))
199 goto end;
200
201 /* Final rule */
202 for (i = 0; i < n; i++) {
203 if (src[i]) {
204 dst[j++] = src[i];
205 src[i] = NULL;
206 }
207 }
208
209 end:
210 return 0;
211}
212
213static int
214__xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
215{
216 int i;
217 int j = 0;
218
219 /* Rule 1: select IPsec transport */
220 for (i = 0; i < n; i++) {
221 if (src[i]->mode == XFRM_MODE_TRANSPORT) {
222 dst[j++] = src[i];
223 src[i] = NULL;
224 }
225 }
226 if (j == n)
227 goto end;
228
229 /* XXX: Rule 2: select MIPv6 RO or inbound trigger */
230
231 /* Rule 3: select IPsec tunnel */
232 for (i = 0; i < n; i++) {
233 if (src[i] &&
234 src[i]->mode == XFRM_MODE_TUNNEL) {
235 dst[j++] = src[i];
236 src[i] = NULL;
237 }
238 }
239 if (likely(j == n))
240 goto end;
241
242 /* Final rule */
243 for (i = 0; i < n; i++) {
244 if (src[i]) {
245 dst[j++] = src[i];
246 src[i] = NULL;
247 }
248 }
249
250 end:
251 return 0;
252}
253
159static struct xfrm_state_afinfo xfrm6_state_afinfo = { 254static struct xfrm_state_afinfo xfrm6_state_afinfo = {
160 .family = AF_INET6, 255 .family = AF_INET6,
161 .init_tempsel = __xfrm6_init_tempsel, 256 .init_tempsel = __xfrm6_init_tempsel,
162 .state_lookup = __xfrm6_state_lookup, 257 .state_lookup = __xfrm6_state_lookup,
163 .state_lookup_byaddr = __xfrm6_state_lookup_byaddr, 258 .state_lookup_byaddr = __xfrm6_state_lookup_byaddr,
164 .find_acq = __xfrm6_find_acq, 259 .find_acq = __xfrm6_find_acq,
260 .tmpl_sort = __xfrm6_tmpl_sort,
261 .state_sort = __xfrm6_state_sort,
165}; 262};
166 263
167void __init xfrm6_state_init(void) 264void __init xfrm6_state_init(void)