]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - net/xfrm/xfrm_state.c
xfrm: state: use atomic_inc_not_zero to increment refcount
[mirror_ubuntu-focal-kernel.git] / net / xfrm / xfrm_state.c
CommitLineData
1da177e4
LT
1/*
2 * xfrm_state.c
3 *
4 * Changes:
5 * Mitsuru KANDA @USAGI
6 * Kazunori MIYAZAWA @USAGI
7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
8 * IPv6 support
9 * YOSHIFUJI Hideaki @USAGI
10 * Split up af-specific functions
11 * Derek Atkins <derek@ihtfp.com>
12 * Add UDP Encapsulation
df71837d 13 *
1da177e4
LT
14 */
15
16#include <linux/workqueue.h>
17#include <net/xfrm.h>
18#include <linux/pfkeyv2.h>
19#include <linux/ipsec.h>
20#include <linux/module.h>
f034b5d4 21#include <linux/cache.h>
68277acc 22#include <linux/audit.h>
b5890d8b 23#include <asm/uaccess.h>
9e0d57fd 24#include <linux/ktime.h>
5a0e3ad6 25#include <linux/slab.h>
9e0d57fd
YP
26#include <linux/interrupt.h>
27#include <linux/kernel.h>
1da177e4 28
44e36b42
DM
29#include "xfrm_hash.h"
30
1da177e4
LT
31/* Each xfrm_state may be linked to two tables:
32
33 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
a624c108 34 2. Hash table by (daddr,family,reqid) to find what SAs exist for given
1da177e4
LT
35 destination/tunnel endpoint. (output)
36 */
37
f034b5d4 38static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
f034b5d4 39
02efdff7
FW
40static inline bool xfrm_state_hold_rcu(struct xfrm_state __rcu *x)
41{
42 return atomic_inc_not_zero(&x->refcnt);
43}
44
64d0cd00 45static inline unsigned int xfrm_dst_hash(struct net *net,
2ab38503
DM
46 const xfrm_address_t *daddr,
47 const xfrm_address_t *saddr,
c1969f29 48 u32 reqid,
a624c108 49 unsigned short family)
f034b5d4 50{
64d0cd00 51 return __xfrm_dst_hash(daddr, saddr, reqid, family, net->xfrm.state_hmask);
f034b5d4
DM
52}
53
64d0cd00 54static inline unsigned int xfrm_src_hash(struct net *net,
2ab38503
DM
55 const xfrm_address_t *daddr,
56 const xfrm_address_t *saddr,
44e36b42 57 unsigned short family)
f034b5d4 58{
64d0cd00 59 return __xfrm_src_hash(daddr, saddr, family, net->xfrm.state_hmask);
f034b5d4
DM
60}
61
f034b5d4 62static inline unsigned int
2ab38503
DM
63xfrm_spi_hash(struct net *net, const xfrm_address_t *daddr,
64 __be32 spi, u8 proto, unsigned short family)
f034b5d4 65{
64d0cd00 66 return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask);
f034b5d4
DM
67}
68
f034b5d4
DM
69static void xfrm_hash_transfer(struct hlist_head *list,
70 struct hlist_head *ndsttable,
71 struct hlist_head *nsrctable,
72 struct hlist_head *nspitable,
73 unsigned int nhashmask)
74{
b67bfe0d 75 struct hlist_node *tmp;
f034b5d4
DM
76 struct xfrm_state *x;
77
b67bfe0d 78 hlist_for_each_entry_safe(x, tmp, list, bydst) {
f034b5d4
DM
79 unsigned int h;
80
c1969f29
DM
81 h = __xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
82 x->props.reqid, x->props.family,
83 nhashmask);
ae3fb6d3 84 hlist_add_head_rcu(&x->bydst, ndsttable + h);
f034b5d4 85
667bbcb6
MN
86 h = __xfrm_src_hash(&x->id.daddr, &x->props.saddr,
87 x->props.family,
f034b5d4 88 nhashmask);
ae3fb6d3 89 hlist_add_head_rcu(&x->bysrc, nsrctable + h);
f034b5d4 90
7b4dc360
MN
91 if (x->id.spi) {
92 h = __xfrm_spi_hash(&x->id.daddr, x->id.spi,
93 x->id.proto, x->props.family,
94 nhashmask);
ae3fb6d3 95 hlist_add_head_rcu(&x->byspi, nspitable + h);
7b4dc360 96 }
f034b5d4
DM
97 }
98}
99
63082733 100static unsigned long xfrm_hash_new_size(unsigned int state_hmask)
f034b5d4 101{
63082733 102 return ((state_hmask + 1) << 1) * sizeof(struct hlist_head);
f034b5d4
DM
103}
104
63082733 105static void xfrm_hash_resize(struct work_struct *work)
f034b5d4 106{
63082733 107 struct net *net = container_of(work, struct net, xfrm.state_hash_work);
f034b5d4
DM
108 struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi;
109 unsigned long nsize, osize;
110 unsigned int nhashmask, ohashmask;
111 int i;
112
63082733 113 nsize = xfrm_hash_new_size(net->xfrm.state_hmask);
44e36b42 114 ndst = xfrm_hash_alloc(nsize);
f034b5d4 115 if (!ndst)
0244790c 116 return;
44e36b42 117 nsrc = xfrm_hash_alloc(nsize);
f034b5d4 118 if (!nsrc) {
44e36b42 119 xfrm_hash_free(ndst, nsize);
0244790c 120 return;
f034b5d4 121 }
44e36b42 122 nspi = xfrm_hash_alloc(nsize);
f034b5d4 123 if (!nspi) {
44e36b42
DM
124 xfrm_hash_free(ndst, nsize);
125 xfrm_hash_free(nsrc, nsize);
0244790c 126 return;
f034b5d4
DM
127 }
128
283bc9f3 129 spin_lock_bh(&net->xfrm.xfrm_state_lock);
f034b5d4
DM
130
131 nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
63082733
AD
132 for (i = net->xfrm.state_hmask; i >= 0; i--)
133 xfrm_hash_transfer(net->xfrm.state_bydst+i, ndst, nsrc, nspi,
f034b5d4
DM
134 nhashmask);
135
63082733
AD
136 odst = net->xfrm.state_bydst;
137 osrc = net->xfrm.state_bysrc;
138 ospi = net->xfrm.state_byspi;
139 ohashmask = net->xfrm.state_hmask;
f034b5d4 140
63082733
AD
141 net->xfrm.state_bydst = ndst;
142 net->xfrm.state_bysrc = nsrc;
143 net->xfrm.state_byspi = nspi;
144 net->xfrm.state_hmask = nhashmask;
f034b5d4 145
283bc9f3 146 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
f034b5d4
DM
147
148 osize = (ohashmask + 1) * sizeof(struct hlist_head);
44e36b42
DM
149 xfrm_hash_free(odst, osize);
150 xfrm_hash_free(osrc, osize);
151 xfrm_hash_free(ospi, osize);
f034b5d4
DM
152}
153
44abdc30
CW
154static DEFINE_SPINLOCK(xfrm_state_afinfo_lock);
155static struct xfrm_state_afinfo __rcu *xfrm_state_afinfo[NPROTO];
1da177e4 156
1da177e4
LT
157static DEFINE_SPINLOCK(xfrm_state_gc_lock);
158
53bc6b4d 159int __xfrm_state_delete(struct xfrm_state *x);
1da177e4 160
980ebd25 161int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
0f24558e 162bool km_is_alive(const struct km_event *c);
15e47304 163void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
1da177e4 164
7a9885b9 165static DEFINE_SPINLOCK(xfrm_type_lock);
533cb5b0 166int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
aa5d62cc 167{
7a9885b9 168 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
533cb5b0 169 const struct xfrm_type **typemap;
aa5d62cc
HX
170 int err = 0;
171
172 if (unlikely(afinfo == NULL))
173 return -EAFNOSUPPORT;
174 typemap = afinfo->type_map;
7a9885b9 175 spin_lock_bh(&xfrm_type_lock);
aa5d62cc
HX
176
177 if (likely(typemap[type->proto] == NULL))
178 typemap[type->proto] = type;
179 else
180 err = -EEXIST;
7a9885b9
CW
181 spin_unlock_bh(&xfrm_type_lock);
182 xfrm_state_put_afinfo(afinfo);
aa5d62cc
HX
183 return err;
184}
185EXPORT_SYMBOL(xfrm_register_type);
186
533cb5b0 187int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family)
aa5d62cc 188{
7a9885b9 189 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
533cb5b0 190 const struct xfrm_type **typemap;
aa5d62cc
HX
191 int err = 0;
192
193 if (unlikely(afinfo == NULL))
194 return -EAFNOSUPPORT;
195 typemap = afinfo->type_map;
7a9885b9 196 spin_lock_bh(&xfrm_type_lock);
aa5d62cc
HX
197
198 if (unlikely(typemap[type->proto] != type))
199 err = -ENOENT;
200 else
201 typemap[type->proto] = NULL;
7a9885b9
CW
202 spin_unlock_bh(&xfrm_type_lock);
203 xfrm_state_put_afinfo(afinfo);
aa5d62cc
HX
204 return err;
205}
206EXPORT_SYMBOL(xfrm_unregister_type);
207
533cb5b0 208static const struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
aa5d62cc
HX
209{
210 struct xfrm_state_afinfo *afinfo;
533cb5b0
ED
211 const struct xfrm_type **typemap;
212 const struct xfrm_type *type;
aa5d62cc
HX
213 int modload_attempted = 0;
214
215retry:
216 afinfo = xfrm_state_get_afinfo(family);
217 if (unlikely(afinfo == NULL))
218 return NULL;
219 typemap = afinfo->type_map;
220
221 type = typemap[proto];
222 if (unlikely(type && !try_module_get(type->owner)))
223 type = NULL;
224 if (!type && !modload_attempted) {
225 xfrm_state_put_afinfo(afinfo);
226 request_module("xfrm-type-%d-%d", family, proto);
227 modload_attempted = 1;
228 goto retry;
229 }
230
231 xfrm_state_put_afinfo(afinfo);
232 return type;
233}
234
533cb5b0 235static void xfrm_put_type(const struct xfrm_type *type)
aa5d62cc
HX
236{
237 module_put(type->owner);
238}
239
7a9885b9 240static DEFINE_SPINLOCK(xfrm_mode_lock);
aa5d62cc
HX
241int xfrm_register_mode(struct xfrm_mode *mode, int family)
242{
243 struct xfrm_state_afinfo *afinfo;
244 struct xfrm_mode **modemap;
245 int err;
246
247 if (unlikely(mode->encap >= XFRM_MODE_MAX))
248 return -EINVAL;
249
7a9885b9 250 afinfo = xfrm_state_get_afinfo(family);
aa5d62cc
HX
251 if (unlikely(afinfo == NULL))
252 return -EAFNOSUPPORT;
253
254 err = -EEXIST;
255 modemap = afinfo->mode_map;
7a9885b9 256 spin_lock_bh(&xfrm_mode_lock);
17c2a42a
HX
257 if (modemap[mode->encap])
258 goto out;
aa5d62cc 259
17c2a42a
HX
260 err = -ENOENT;
261 if (!try_module_get(afinfo->owner))
262 goto out;
263
264 mode->afinfo = afinfo;
265 modemap[mode->encap] = mode;
266 err = 0;
267
268out:
7a9885b9
CW
269 spin_unlock_bh(&xfrm_mode_lock);
270 xfrm_state_put_afinfo(afinfo);
aa5d62cc
HX
271 return err;
272}
273EXPORT_SYMBOL(xfrm_register_mode);
274
275int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
276{
277 struct xfrm_state_afinfo *afinfo;
278 struct xfrm_mode **modemap;
279 int err;
280
281 if (unlikely(mode->encap >= XFRM_MODE_MAX))
282 return -EINVAL;
283
7a9885b9 284 afinfo = xfrm_state_get_afinfo(family);
aa5d62cc
HX
285 if (unlikely(afinfo == NULL))
286 return -EAFNOSUPPORT;
287
288 err = -ENOENT;
289 modemap = afinfo->mode_map;
7a9885b9 290 spin_lock_bh(&xfrm_mode_lock);
aa5d62cc
HX
291 if (likely(modemap[mode->encap] == mode)) {
292 modemap[mode->encap] = NULL;
17c2a42a 293 module_put(mode->afinfo->owner);
aa5d62cc
HX
294 err = 0;
295 }
296
7a9885b9
CW
297 spin_unlock_bh(&xfrm_mode_lock);
298 xfrm_state_put_afinfo(afinfo);
aa5d62cc
HX
299 return err;
300}
301EXPORT_SYMBOL(xfrm_unregister_mode);
302
303static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
304{
305 struct xfrm_state_afinfo *afinfo;
306 struct xfrm_mode *mode;
307 int modload_attempted = 0;
308
309 if (unlikely(encap >= XFRM_MODE_MAX))
310 return NULL;
311
312retry:
313 afinfo = xfrm_state_get_afinfo(family);
314 if (unlikely(afinfo == NULL))
315 return NULL;
316
317 mode = afinfo->mode_map[encap];
318 if (unlikely(mode && !try_module_get(mode->owner)))
319 mode = NULL;
320 if (!mode && !modload_attempted) {
321 xfrm_state_put_afinfo(afinfo);
322 request_module("xfrm-mode-%d-%d", family, encap);
323 modload_attempted = 1;
324 goto retry;
325 }
326
327 xfrm_state_put_afinfo(afinfo);
328 return mode;
329}
330
331static void xfrm_put_mode(struct xfrm_mode *mode)
332{
333 module_put(mode->owner);
334}
335
1da177e4
LT
336static void xfrm_state_gc_destroy(struct xfrm_state *x)
337{
9e0d57fd 338 tasklet_hrtimer_cancel(&x->mtimer);
a47f0ce0 339 del_timer_sync(&x->rtimer);
a51482bd
JJ
340 kfree(x->aalg);
341 kfree(x->ealg);
342 kfree(x->calg);
343 kfree(x->encap);
060f02a3 344 kfree(x->coaddr);
d8647b79
SK
345 kfree(x->replay_esn);
346 kfree(x->preplay_esn);
13996378
HX
347 if (x->inner_mode)
348 xfrm_put_mode(x->inner_mode);
df9dcb45
KM
349 if (x->inner_mode_iaf)
350 xfrm_put_mode(x->inner_mode_iaf);
13996378
HX
351 if (x->outer_mode)
352 xfrm_put_mode(x->outer_mode);
1da177e4
LT
353 if (x->type) {
354 x->type->destructor(x);
355 xfrm_put_type(x->type);
356 }
df71837d 357 security_xfrm_state_free(x);
1da177e4
LT
358 kfree(x);
359}
360
c7837144 361static void xfrm_state_gc_task(struct work_struct *work)
1da177e4 362{
c7837144 363 struct net *net = container_of(work, struct net, xfrm.state_gc_work);
12a169e7 364 struct xfrm_state *x;
b67bfe0d 365 struct hlist_node *tmp;
12a169e7 366 struct hlist_head gc_list;
1da177e4 367
1da177e4 368 spin_lock_bh(&xfrm_state_gc_lock);
c7837144 369 hlist_move_list(&net->xfrm.state_gc_list, &gc_list);
1da177e4
LT
370 spin_unlock_bh(&xfrm_state_gc_lock);
371
b67bfe0d 372 hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
1da177e4 373 xfrm_state_gc_destroy(x);
1da177e4
LT
374}
375
376static inline unsigned long make_jiffies(long secs)
377{
378 if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
379 return MAX_SCHEDULE_TIMEOUT-1;
380 else
a716c119 381 return secs*HZ;
1da177e4
LT
382}
383
3e94c2dc 384static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
1da177e4 385{
9e0d57fd
YP
386 struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer);
387 struct xfrm_state *x = container_of(thr, struct xfrm_state, mtimer);
9d729f72 388 unsigned long now = get_seconds();
1da177e4
LT
389 long next = LONG_MAX;
390 int warn = 0;
161a09e7 391 int err = 0;
1da177e4
LT
392
393 spin_lock(&x->lock);
394 if (x->km.state == XFRM_STATE_DEAD)
395 goto out;
396 if (x->km.state == XFRM_STATE_EXPIRED)
397 goto expired;
398 if (x->lft.hard_add_expires_seconds) {
399 long tmo = x->lft.hard_add_expires_seconds +
400 x->curlft.add_time - now;
e3c0d047
FD
401 if (tmo <= 0) {
402 if (x->xflags & XFRM_SOFT_EXPIRE) {
403 /* enter hard expire without soft expire first?!
404 * setting a new date could trigger this.
405 * workarbound: fix x->curflt.add_time by below:
406 */
407 x->curlft.add_time = now - x->saved_tmo - 1;
408 tmo = x->lft.hard_add_expires_seconds - x->saved_tmo;
409 } else
410 goto expired;
411 }
1da177e4
LT
412 if (tmo < next)
413 next = tmo;
414 }
415 if (x->lft.hard_use_expires_seconds) {
416 long tmo = x->lft.hard_use_expires_seconds +
417 (x->curlft.use_time ? : now) - now;
418 if (tmo <= 0)
419 goto expired;
420 if (tmo < next)
421 next = tmo;
422 }
423 if (x->km.dying)
424 goto resched;
425 if (x->lft.soft_add_expires_seconds) {
426 long tmo = x->lft.soft_add_expires_seconds +
427 x->curlft.add_time - now;
e3c0d047 428 if (tmo <= 0) {
1da177e4 429 warn = 1;
e3c0d047
FD
430 x->xflags &= ~XFRM_SOFT_EXPIRE;
431 } else if (tmo < next) {
1da177e4 432 next = tmo;
e3c0d047
FD
433 x->xflags |= XFRM_SOFT_EXPIRE;
434 x->saved_tmo = tmo;
435 }
1da177e4
LT
436 }
437 if (x->lft.soft_use_expires_seconds) {
438 long tmo = x->lft.soft_use_expires_seconds +
439 (x->curlft.use_time ? : now) - now;
440 if (tmo <= 0)
441 warn = 1;
442 else if (tmo < next)
443 next = tmo;
444 }
445
4666faab 446 x->km.dying = warn;
1da177e4 447 if (warn)
53bc6b4d 448 km_state_expired(x, 0, 0);
1da177e4 449resched:
9b7a787d 450 if (next != LONG_MAX) {
9e0d57fd
YP
451 tasklet_hrtimer_start(&x->mtimer, ktime_set(next, 0), HRTIMER_MODE_REL);
452 }
a47f0ce0 453
1da177e4
LT
454 goto out;
455
456expired:
5b8ef341 457 if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0)
1da177e4 458 x->km.state = XFRM_STATE_EXPIRED;
161a09e7
JL
459
460 err = __xfrm_state_delete(x);
0806ae4c 461 if (!err)
53bc6b4d 462 km_state_expired(x, 1, 0);
1da177e4 463
2e71029e 464 xfrm_audit_state_delete(x, err ? 0 : 1, true);
161a09e7 465
1da177e4
LT
466out:
467 spin_unlock(&x->lock);
9e0d57fd 468 return HRTIMER_NORESTART;
1da177e4
LT
469}
470
0ac84752
DM
471static void xfrm_replay_timer_handler(unsigned long data);
472
673c09be 473struct xfrm_state *xfrm_state_alloc(struct net *net)
1da177e4
LT
474{
475 struct xfrm_state *x;
476
0da974f4 477 x = kzalloc(sizeof(struct xfrm_state), GFP_ATOMIC);
1da177e4
LT
478
479 if (x) {
673c09be 480 write_pnet(&x->xs_net, net);
1da177e4
LT
481 atomic_set(&x->refcnt, 1);
482 atomic_set(&x->tunnel_users, 0);
12a169e7 483 INIT_LIST_HEAD(&x->km.all);
8f126e37
DM
484 INIT_HLIST_NODE(&x->bydst);
485 INIT_HLIST_NODE(&x->bysrc);
486 INIT_HLIST_NODE(&x->byspi);
99565a6c
FD
487 tasklet_hrtimer_init(&x->mtimer, xfrm_timer_handler,
488 CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
b24b8a24
PE
489 setup_timer(&x->rtimer, xfrm_replay_timer_handler,
490 (unsigned long)x);
9d729f72 491 x->curlft.add_time = get_seconds();
1da177e4
LT
492 x->lft.soft_byte_limit = XFRM_INF;
493 x->lft.soft_packet_limit = XFRM_INF;
494 x->lft.hard_byte_limit = XFRM_INF;
495 x->lft.hard_packet_limit = XFRM_INF;
f8cd5488
JHS
496 x->replay_maxage = 0;
497 x->replay_maxdiff = 0;
df9dcb45
KM
498 x->inner_mode = NULL;
499 x->inner_mode_iaf = NULL;
1da177e4
LT
500 spin_lock_init(&x->lock);
501 }
502 return x;
503}
504EXPORT_SYMBOL(xfrm_state_alloc);
505
506void __xfrm_state_destroy(struct xfrm_state *x)
507{
98806f75
AD
508 struct net *net = xs_net(x);
509
547b792c 510 WARN_ON(x->km.state != XFRM_STATE_DEAD);
1da177e4
LT
511
512 spin_lock_bh(&xfrm_state_gc_lock);
98806f75 513 hlist_add_head(&x->gclist, &net->xfrm.state_gc_list);
1da177e4 514 spin_unlock_bh(&xfrm_state_gc_lock);
98806f75 515 schedule_work(&net->xfrm.state_gc_work);
1da177e4
LT
516}
517EXPORT_SYMBOL(__xfrm_state_destroy);
518
53bc6b4d 519int __xfrm_state_delete(struct xfrm_state *x)
1da177e4 520{
98806f75 521 struct net *net = xs_net(x);
26b15dad
JHS
522 int err = -ESRCH;
523
1da177e4
LT
524 if (x->km.state != XFRM_STATE_DEAD) {
525 x->km.state = XFRM_STATE_DEAD;
283bc9f3 526 spin_lock(&net->xfrm.xfrm_state_lock);
12a169e7 527 list_del(&x->km.all);
ae3fb6d3
FW
528 hlist_del_rcu(&x->bydst);
529 hlist_del_rcu(&x->bysrc);
a47f0ce0 530 if (x->id.spi)
ae3fb6d3 531 hlist_del_rcu(&x->byspi);
98806f75 532 net->xfrm.state_num--;
283bc9f3 533 spin_unlock(&net->xfrm.xfrm_state_lock);
1da177e4 534
1da177e4
LT
535 /* All xfrm_state objects are created by xfrm_state_alloc.
536 * The xfrm_state_alloc call gives a reference, and that
537 * is what we are dropping here.
538 */
5dba4797 539 xfrm_state_put(x);
26b15dad 540 err = 0;
1da177e4 541 }
26b15dad
JHS
542
543 return err;
1da177e4 544}
53bc6b4d 545EXPORT_SYMBOL(__xfrm_state_delete);
1da177e4 546
26b15dad 547int xfrm_state_delete(struct xfrm_state *x)
1da177e4 548{
26b15dad
JHS
549 int err;
550
1da177e4 551 spin_lock_bh(&x->lock);
26b15dad 552 err = __xfrm_state_delete(x);
1da177e4 553 spin_unlock_bh(&x->lock);
26b15dad
JHS
554
555 return err;
1da177e4
LT
556}
557EXPORT_SYMBOL(xfrm_state_delete);
558
4aa2e62c
JL
559#ifdef CONFIG_SECURITY_NETWORK_XFRM
560static inline int
2e71029e 561xfrm_state_flush_secctx_check(struct net *net, u8 proto, bool task_valid)
1da177e4 562{
4aa2e62c
JL
563 int i, err = 0;
564
0e602451 565 for (i = 0; i <= net->xfrm.state_hmask; i++) {
4aa2e62c
JL
566 struct xfrm_state *x;
567
b67bfe0d 568 hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) {
4aa2e62c
JL
569 if (xfrm_id_proto_match(x->id.proto, proto) &&
570 (err = security_xfrm_state_delete(x)) != 0) {
2e71029e 571 xfrm_audit_state_delete(x, 0, task_valid);
4aa2e62c
JL
572 return err;
573 }
574 }
575 }
576
577 return err;
578}
579#else
580static inline int
2e71029e 581xfrm_state_flush_secctx_check(struct net *net, u8 proto, bool task_valid)
4aa2e62c
JL
582{
583 return 0;
584}
585#endif
586
2e71029e 587int xfrm_state_flush(struct net *net, u8 proto, bool task_valid)
4aa2e62c 588{
9e64cc95 589 int i, err = 0, cnt = 0;
1da177e4 590
283bc9f3 591 spin_lock_bh(&net->xfrm.xfrm_state_lock);
2e71029e 592 err = xfrm_state_flush_secctx_check(net, proto, task_valid);
4aa2e62c
JL
593 if (err)
594 goto out;
595
9e64cc95 596 err = -ESRCH;
0e602451 597 for (i = 0; i <= net->xfrm.state_hmask; i++) {
8f126e37 598 struct xfrm_state *x;
1da177e4 599restart:
b67bfe0d 600 hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) {
1da177e4 601 if (!xfrm_state_kern(x) &&
5794708f 602 xfrm_id_proto_match(x->id.proto, proto)) {
1da177e4 603 xfrm_state_hold(x);
283bc9f3 604 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4 605
161a09e7 606 err = xfrm_state_delete(x);
ab5f5e8b 607 xfrm_audit_state_delete(x, err ? 0 : 1,
2e71029e 608 task_valid);
1da177e4 609 xfrm_state_put(x);
9e64cc95
JHS
610 if (!err)
611 cnt++;
1da177e4 612
283bc9f3 613 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1da177e4
LT
614 goto restart;
615 }
616 }
617 }
9e64cc95
JHS
618 if (cnt)
619 err = 0;
4aa2e62c
JL
620
621out:
283bc9f3 622 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
4aa2e62c 623 return err;
1da177e4
LT
624}
625EXPORT_SYMBOL(xfrm_state_flush);
626
e071041b 627void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
28d8909b 628{
283bc9f3 629 spin_lock_bh(&net->xfrm.xfrm_state_lock);
e071041b
AD
630 si->sadcnt = net->xfrm.state_num;
631 si->sadhcnt = net->xfrm.state_hmask;
28d8909b 632 si->sadhmcnt = xfrm_state_hashmax;
283bc9f3 633 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
28d8909b
JHS
634}
635EXPORT_SYMBOL(xfrm_sad_getinfo);
636
1da177e4 637static int
1a898592 638xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl,
04686013 639 const struct xfrm_tmpl *tmpl,
33765d06 640 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
8444cf71 641 unsigned short family)
1da177e4
LT
642{
643 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
644 if (!afinfo)
645 return -1;
8444cf71
TE
646 afinfo->init_tempsel(&x->sel, fl);
647
648 if (family != tmpl->encap_family) {
649 xfrm_state_put_afinfo(afinfo);
650 afinfo = xfrm_state_get_afinfo(tmpl->encap_family);
651 if (!afinfo)
652 return -1;
653 }
654 afinfo->init_temprop(x, tmpl, daddr, saddr);
1da177e4
LT
655 xfrm_state_put_afinfo(afinfo);
656 return 0;
657}
658
9aa60088
DM
659static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark,
660 const xfrm_address_t *daddr,
661 __be32 spi, u8 proto,
662 unsigned short family)
edcd5821 663{
221df1ed 664 unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
edcd5821
DM
665 struct xfrm_state *x;
666
ae3fb6d3 667 hlist_for_each_entry_rcu(x, net->xfrm.state_byspi + h, byspi) {
edcd5821
DM
668 if (x->props.family != family ||
669 x->id.spi != spi ||
1802571b 670 x->id.proto != proto ||
70e94e66 671 !xfrm_addr_equal(&x->id.daddr, daddr, family))
edcd5821
DM
672 continue;
673
3d6acfa7
JHS
674 if ((mark & x->mark.m) != x->mark.v)
675 continue;
02efdff7
FW
676 if (!xfrm_state_hold_rcu(x))
677 continue;
edcd5821
DM
678 return x;
679 }
680
681 return NULL;
682}
683
9aa60088
DM
684static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark,
685 const xfrm_address_t *daddr,
686 const xfrm_address_t *saddr,
687 u8 proto, unsigned short family)
edcd5821 688{
221df1ed 689 unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
edcd5821
DM
690 struct xfrm_state *x;
691
ae3fb6d3 692 hlist_for_each_entry_rcu(x, net->xfrm.state_bysrc + h, bysrc) {
edcd5821 693 if (x->props.family != family ||
1802571b 694 x->id.proto != proto ||
70e94e66
YH
695 !xfrm_addr_equal(&x->id.daddr, daddr, family) ||
696 !xfrm_addr_equal(&x->props.saddr, saddr, family))
edcd5821
DM
697 continue;
698
3d6acfa7
JHS
699 if ((mark & x->mark.m) != x->mark.v)
700 continue;
02efdff7
FW
701 if (!xfrm_state_hold_rcu(x))
702 continue;
edcd5821
DM
703 return x;
704 }
705
706 return NULL;
707}
708
709static inline struct xfrm_state *
710__xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
711{
221df1ed 712 struct net *net = xs_net(x);
bd55775c 713 u32 mark = x->mark.v & x->mark.m;
221df1ed 714
edcd5821 715 if (use_spi)
bd55775c
JHS
716 return __xfrm_state_lookup(net, mark, &x->id.daddr,
717 x->id.spi, x->id.proto, family);
edcd5821 718 else
bd55775c
JHS
719 return __xfrm_state_lookup_byaddr(net, mark,
720 &x->id.daddr,
edcd5821
DM
721 &x->props.saddr,
722 x->id.proto, family);
723}
724
98806f75 725static void xfrm_hash_grow_check(struct net *net, int have_hash_collision)
2fab22f2
PM
726{
727 if (have_hash_collision &&
98806f75
AD
728 (net->xfrm.state_hmask + 1) < xfrm_state_hashmax &&
729 net->xfrm.state_num > net->xfrm.state_hmask)
730 schedule_work(&net->xfrm.state_hash_work);
2fab22f2
PM
731}
732
08ec9af1 733static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
4a08ab0f 734 const struct flowi *fl, unsigned short family,
08ec9af1
DM
735 struct xfrm_state **best, int *acq_in_progress,
736 int *error)
737{
738 /* Resolution logic:
739 * 1. There is a valid state with matching selector. Done.
740 * 2. Valid state with inappropriate selector. Skip.
741 *
742 * Entering area of "sysdeps".
743 *
744 * 3. If state is not valid, selector is temporary, it selects
745 * only session which triggered previous resolution. Key
746 * manager will do something to install a state with proper
747 * selector.
748 */
749 if (x->km.state == XFRM_STATE_VALID) {
750 if ((x->sel.family &&
751 !xfrm_selector_match(&x->sel, fl, x->sel.family)) ||
752 !security_xfrm_state_pol_flow_match(x, pol, fl))
753 return;
754
755 if (!*best ||
756 (*best)->km.dying > x->km.dying ||
757 ((*best)->km.dying == x->km.dying &&
758 (*best)->curlft.add_time < x->curlft.add_time))
759 *best = x;
760 } else if (x->km.state == XFRM_STATE_ACQ) {
761 *acq_in_progress = 1;
762 } else if (x->km.state == XFRM_STATE_ERROR ||
763 x->km.state == XFRM_STATE_EXPIRED) {
764 if (xfrm_selector_match(&x->sel, fl, x->sel.family) &&
765 security_xfrm_state_pol_flow_match(x, pol, fl))
766 *error = -ESRCH;
767 }
768}
769
1da177e4 770struct xfrm_state *
33765d06 771xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
b520e9f6 772 const struct flowi *fl, struct xfrm_tmpl *tmpl,
1da177e4
LT
773 struct xfrm_policy *pol, int *err,
774 unsigned short family)
775{
08ec9af1 776 static xfrm_address_t saddr_wildcard = { };
5447c5e4 777 struct net *net = xp_net(pol);
6a783c90 778 unsigned int h, h_wildcard;
37b08e34 779 struct xfrm_state *x, *x0, *to_put;
1da177e4
LT
780 int acquire_in_progress = 0;
781 int error = 0;
782 struct xfrm_state *best = NULL;
bd55775c 783 u32 mark = pol->mark.v & pol->mark.m;
8444cf71 784 unsigned short encap_family = tmpl->encap_family;
0f24558e 785 struct km_event c;
a716c119 786
37b08e34
DM
787 to_put = NULL;
788
283bc9f3 789 spin_lock_bh(&net->xfrm.xfrm_state_lock);
8444cf71 790 h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
ae3fb6d3 791 hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) {
8444cf71 792 if (x->props.family == encap_family &&
1da177e4 793 x->props.reqid == tmpl->reqid &&
3d6acfa7 794 (mark & x->mark.m) == x->mark.v &&
fbd9a5b4 795 !(x->props.flags & XFRM_STATE_WILDRECV) &&
8444cf71 796 xfrm_state_addr_check(x, daddr, saddr, encap_family) &&
1da177e4
LT
797 tmpl->mode == x->props.mode &&
798 tmpl->id.proto == x->id.proto &&
08ec9af1 799 (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
1f673c5f 800 xfrm_state_look_at(pol, x, fl, encap_family,
08ec9af1
DM
801 &best, &acquire_in_progress, &error);
802 }
6f115638 803 if (best || acquire_in_progress)
08ec9af1
DM
804 goto found;
805
8444cf71 806 h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family);
ae3fb6d3 807 hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h_wildcard, bydst) {
8444cf71 808 if (x->props.family == encap_family &&
08ec9af1 809 x->props.reqid == tmpl->reqid &&
3d6acfa7 810 (mark & x->mark.m) == x->mark.v &&
08ec9af1 811 !(x->props.flags & XFRM_STATE_WILDRECV) &&
f59bbdfa 812 xfrm_addr_equal(&x->id.daddr, daddr, encap_family) &&
08ec9af1
DM
813 tmpl->mode == x->props.mode &&
814 tmpl->id.proto == x->id.proto &&
815 (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
1f673c5f 816 xfrm_state_look_at(pol, x, fl, encap_family,
08ec9af1 817 &best, &acquire_in_progress, &error);
1da177e4
LT
818 }
819
08ec9af1 820found:
1da177e4
LT
821 x = best;
822 if (!x && !error && !acquire_in_progress) {
5c5d281a 823 if (tmpl->id.spi &&
bd55775c 824 (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
8444cf71 825 tmpl->id.proto, encap_family)) != NULL) {
37b08e34 826 to_put = x0;
1da177e4
LT
827 error = -EEXIST;
828 goto out;
829 }
0f24558e
HG
830
831 c.net = net;
832 /* If the KMs have no listeners (yet...), avoid allocating an SA
833 * for each and every packet - garbage collection might not
834 * handle the flood.
835 */
836 if (!km_is_alive(&c)) {
837 error = -ESRCH;
838 goto out;
839 }
840
5447c5e4 841 x = xfrm_state_alloc(net);
1da177e4
LT
842 if (x == NULL) {
843 error = -ENOMEM;
844 goto out;
845 }
8444cf71 846 /* Initialize temporary state matching only
1da177e4 847 * to current session. */
8444cf71 848 xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family);
bd55775c 849 memcpy(&x->mark, &pol->mark, sizeof(x->mark));
1da177e4 850
1d28f42c 851 error = security_xfrm_state_alloc_acquire(x, pol->security, fl->flowi_secid);
e0d1caa7
VY
852 if (error) {
853 x->km.state = XFRM_STATE_DEAD;
37b08e34 854 to_put = x;
e0d1caa7
VY
855 x = NULL;
856 goto out;
857 }
858
1da177e4
LT
859 if (km_query(x, tmpl, pol) == 0) {
860 x->km.state = XFRM_STATE_ACQ;
5447c5e4 861 list_add(&x->km.all, &net->xfrm.state_all);
ae3fb6d3 862 hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h);
8444cf71 863 h = xfrm_src_hash(net, daddr, saddr, encap_family);
ae3fb6d3 864 hlist_add_head_rcu(&x->bysrc, net->xfrm.state_bysrc + h);
1da177e4 865 if (x->id.spi) {
8444cf71 866 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family);
ae3fb6d3 867 hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
1da177e4 868 }
b27aeadb 869 x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
9e0d57fd 870 tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL);
5447c5e4
AD
871 net->xfrm.state_num++;
872 xfrm_hash_grow_check(net, x->bydst.next != NULL);
1da177e4
LT
873 } else {
874 x->km.state = XFRM_STATE_DEAD;
37b08e34 875 to_put = x;
1da177e4
LT
876 x = NULL;
877 error = -ESRCH;
878 }
879 }
880out:
02efdff7
FW
881 if (x) {
882 if (!xfrm_state_hold_rcu(x)) {
883 *err = -EAGAIN;
884 x = NULL;
885 }
886 } else {
1da177e4 887 *err = acquire_in_progress ? -EAGAIN : error;
02efdff7 888 }
283bc9f3 889 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
37b08e34
DM
890 if (to_put)
891 xfrm_state_put(to_put);
1da177e4
LT
892 return x;
893}
894
628529b6 895struct xfrm_state *
bd55775c 896xfrm_stateonly_find(struct net *net, u32 mark,
5447c5e4 897 xfrm_address_t *daddr, xfrm_address_t *saddr,
628529b6
JHS
898 unsigned short family, u8 mode, u8 proto, u32 reqid)
899{
4bda4f25 900 unsigned int h;
628529b6 901 struct xfrm_state *rx = NULL, *x = NULL;
628529b6 902
4ae770bf 903 spin_lock_bh(&net->xfrm.xfrm_state_lock);
5447c5e4 904 h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
b67bfe0d 905 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
628529b6
JHS
906 if (x->props.family == family &&
907 x->props.reqid == reqid &&
3d6acfa7 908 (mark & x->mark.m) == x->mark.v &&
628529b6
JHS
909 !(x->props.flags & XFRM_STATE_WILDRECV) &&
910 xfrm_state_addr_check(x, daddr, saddr, family) &&
911 mode == x->props.mode &&
912 proto == x->id.proto &&
913 x->km.state == XFRM_STATE_VALID) {
914 rx = x;
915 break;
916 }
917 }
918
919 if (rx)
920 xfrm_state_hold(rx);
4ae770bf 921 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
628529b6
JHS
922
923
924 return rx;
925}
926EXPORT_SYMBOL(xfrm_stateonly_find);
927
c454997e
FD
928struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
929 unsigned short family)
930{
931 struct xfrm_state *x;
932 struct xfrm_state_walk *w;
933
934 spin_lock_bh(&net->xfrm.xfrm_state_lock);
935 list_for_each_entry(w, &net->xfrm.state_all, all) {
936 x = container_of(w, struct xfrm_state, km);
937 if (x->props.family != family ||
938 x->id.spi != spi)
939 continue;
940
c454997e 941 xfrm_state_hold(x);
bdddbf69 942 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
c454997e
FD
943 return x;
944 }
945 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
946 return NULL;
947}
948EXPORT_SYMBOL(xfrm_state_lookup_byspi);
949
1da177e4
LT
950static void __xfrm_state_insert(struct xfrm_state *x)
951{
98806f75 952 struct net *net = xs_net(x);
a624c108 953 unsigned int h;
1da177e4 954
98806f75 955 list_add(&x->km.all, &net->xfrm.state_all);
4c563f76 956
98806f75 957 h = xfrm_dst_hash(net, &x->id.daddr, &x->props.saddr,
c1969f29 958 x->props.reqid, x->props.family);
ae3fb6d3 959 hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h);
1da177e4 960
98806f75 961 h = xfrm_src_hash(net, &x->id.daddr, &x->props.saddr, x->props.family);
ae3fb6d3 962 hlist_add_head_rcu(&x->bysrc, net->xfrm.state_bysrc + h);
1da177e4 963
7b4dc360 964 if (x->id.spi) {
98806f75 965 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto,
6c44e6b7
MN
966 x->props.family);
967
ae3fb6d3 968 hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
6c44e6b7
MN
969 }
970
9e0d57fd 971 tasklet_hrtimer_start(&x->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL);
a47f0ce0
DM
972 if (x->replay_maxage)
973 mod_timer(&x->rtimer, jiffies + x->replay_maxage);
f8cd5488 974
98806f75 975 net->xfrm.state_num++;
f034b5d4 976
98806f75 977 xfrm_hash_grow_check(net, x->bydst.next != NULL);
1da177e4
LT
978}
979
283bc9f3 980/* net->xfrm.xfrm_state_lock is held */
c7f5ea3a
DM
981static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
982{
98806f75 983 struct net *net = xs_net(xnew);
c7f5ea3a
DM
984 unsigned short family = xnew->props.family;
985 u32 reqid = xnew->props.reqid;
986 struct xfrm_state *x;
c7f5ea3a 987 unsigned int h;
3d6acfa7 988 u32 mark = xnew->mark.v & xnew->mark.m;
c7f5ea3a 989
98806f75 990 h = xfrm_dst_hash(net, &xnew->id.daddr, &xnew->props.saddr, reqid, family);
b67bfe0d 991 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
c7f5ea3a
DM
992 if (x->props.family == family &&
993 x->props.reqid == reqid &&
3d6acfa7 994 (mark & x->mark.m) == x->mark.v &&
70e94e66
YH
995 xfrm_addr_equal(&x->id.daddr, &xnew->id.daddr, family) &&
996 xfrm_addr_equal(&x->props.saddr, &xnew->props.saddr, family))
34996cb9 997 x->genid++;
c7f5ea3a
DM
998 }
999}
1000
1da177e4
LT
1001void xfrm_state_insert(struct xfrm_state *x)
1002{
283bc9f3
FD
1003 struct net *net = xs_net(x);
1004
1005 spin_lock_bh(&net->xfrm.xfrm_state_lock);
c7f5ea3a 1006 __xfrm_state_bump_genids(x);
1da177e4 1007 __xfrm_state_insert(x);
283bc9f3 1008 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4
LT
1009}
1010EXPORT_SYMBOL(xfrm_state_insert);
1011
283bc9f3 1012/* net->xfrm.xfrm_state_lock is held */
e473fcb4
MK
1013static struct xfrm_state *__find_acq_core(struct net *net,
1014 const struct xfrm_mark *m,
a70486f0
DM
1015 unsigned short family, u8 mode,
1016 u32 reqid, u8 proto,
1017 const xfrm_address_t *daddr,
e473fcb4
MK
1018 const xfrm_address_t *saddr,
1019 int create)
2770834c 1020{
5447c5e4 1021 unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
2770834c 1022 struct xfrm_state *x;
3d6acfa7 1023 u32 mark = m->v & m->m;
2770834c 1024
b67bfe0d 1025 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
2770834c
DM
1026 if (x->props.reqid != reqid ||
1027 x->props.mode != mode ||
1028 x->props.family != family ||
1029 x->km.state != XFRM_STATE_ACQ ||
75e252d9 1030 x->id.spi != 0 ||
1802571b 1031 x->id.proto != proto ||
3d6acfa7 1032 (mark & x->mark.m) != x->mark.v ||
70e94e66
YH
1033 !xfrm_addr_equal(&x->id.daddr, daddr, family) ||
1034 !xfrm_addr_equal(&x->props.saddr, saddr, family))
2770834c
DM
1035 continue;
1036
2770834c
DM
1037 xfrm_state_hold(x);
1038 return x;
1039 }
1040
1041 if (!create)
1042 return NULL;
1043
5447c5e4 1044 x = xfrm_state_alloc(net);
2770834c
DM
1045 if (likely(x)) {
1046 switch (family) {
1047 case AF_INET:
1048 x->sel.daddr.a4 = daddr->a4;
1049 x->sel.saddr.a4 = saddr->a4;
1050 x->sel.prefixlen_d = 32;
1051 x->sel.prefixlen_s = 32;
1052 x->props.saddr.a4 = saddr->a4;
1053 x->id.daddr.a4 = daddr->a4;
1054 break;
1055
1056 case AF_INET6:
15e318bd
JB
1057 x->sel.daddr.in6 = daddr->in6;
1058 x->sel.saddr.in6 = saddr->in6;
2770834c
DM
1059 x->sel.prefixlen_d = 128;
1060 x->sel.prefixlen_s = 128;
15e318bd
JB
1061 x->props.saddr.in6 = saddr->in6;
1062 x->id.daddr.in6 = daddr->in6;
2770834c 1063 break;
3ff50b79 1064 }
2770834c
DM
1065
1066 x->km.state = XFRM_STATE_ACQ;
1067 x->id.proto = proto;
1068 x->props.family = family;
1069 x->props.mode = mode;
1070 x->props.reqid = reqid;
bd55775c
JHS
1071 x->mark.v = m->v;
1072 x->mark.m = m->m;
b27aeadb 1073 x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
2770834c 1074 xfrm_state_hold(x);
9e0d57fd 1075 tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL);
5447c5e4 1076 list_add(&x->km.all, &net->xfrm.state_all);
ae3fb6d3 1077 hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h);
5447c5e4 1078 h = xfrm_src_hash(net, daddr, saddr, family);
ae3fb6d3 1079 hlist_add_head_rcu(&x->bysrc, net->xfrm.state_bysrc + h);
918049f0 1080
5447c5e4 1081 net->xfrm.state_num++;
918049f0 1082
5447c5e4 1083 xfrm_hash_grow_check(net, x->bydst.next != NULL);
2770834c
DM
1084 }
1085
1086 return x;
1087}
1088
bd55775c 1089static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1da177e4
LT
1090
1091int xfrm_state_add(struct xfrm_state *x)
1092{
5447c5e4 1093 struct net *net = xs_net(x);
37b08e34 1094 struct xfrm_state *x1, *to_put;
1da177e4
LT
1095 int family;
1096 int err;
bd55775c 1097 u32 mark = x->mark.v & x->mark.m;
eb2971b6 1098 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1da177e4
LT
1099
1100 family = x->props.family;
1da177e4 1101
37b08e34
DM
1102 to_put = NULL;
1103
283bc9f3 1104 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1da177e4 1105
edcd5821 1106 x1 = __xfrm_state_locate(x, use_spi, family);
1da177e4 1107 if (x1) {
37b08e34 1108 to_put = x1;
1da177e4
LT
1109 x1 = NULL;
1110 err = -EEXIST;
1111 goto out;
1112 }
1113
eb2971b6 1114 if (use_spi && x->km.seq) {
bd55775c 1115 x1 = __xfrm_find_acq_byseq(net, mark, x->km.seq);
75e252d9 1116 if (x1 && ((x1->id.proto != x->id.proto) ||
70e94e66 1117 !xfrm_addr_equal(&x1->id.daddr, &x->id.daddr, family))) {
37b08e34 1118 to_put = x1;
1da177e4
LT
1119 x1 = NULL;
1120 }
1121 }
1122
eb2971b6 1123 if (use_spi && !x1)
bd55775c
JHS
1124 x1 = __find_acq_core(net, &x->mark, family, x->props.mode,
1125 x->props.reqid, x->id.proto,
2770834c 1126 &x->id.daddr, &x->props.saddr, 0);
1da177e4 1127
c7f5ea3a 1128 __xfrm_state_bump_genids(x);
1da177e4
LT
1129 __xfrm_state_insert(x);
1130 err = 0;
1131
1132out:
283bc9f3 1133 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4
LT
1134
1135 if (x1) {
1136 xfrm_state_delete(x1);
1137 xfrm_state_put(x1);
1138 }
1139
37b08e34
DM
1140 if (to_put)
1141 xfrm_state_put(to_put);
1142
1da177e4
LT
1143 return err;
1144}
1145EXPORT_SYMBOL(xfrm_state_add);
1146
80c9abaa 1147#ifdef CONFIG_XFRM_MIGRATE
cc9ab60e 1148static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
80c9abaa 1149{
98806f75 1150 struct net *net = xs_net(orig);
98806f75 1151 struct xfrm_state *x = xfrm_state_alloc(net);
80c9abaa 1152 if (!x)
553f9118 1153 goto out;
80c9abaa
SS
1154
1155 memcpy(&x->id, &orig->id, sizeof(x->id));
1156 memcpy(&x->sel, &orig->sel, sizeof(x->sel));
1157 memcpy(&x->lft, &orig->lft, sizeof(x->lft));
1158 x->props.mode = orig->props.mode;
1159 x->props.replay_window = orig->props.replay_window;
1160 x->props.reqid = orig->props.reqid;
1161 x->props.family = orig->props.family;
1162 x->props.saddr = orig->props.saddr;
1163
1164 if (orig->aalg) {
4447bb33 1165 x->aalg = xfrm_algo_auth_clone(orig->aalg);
80c9abaa
SS
1166 if (!x->aalg)
1167 goto error;
1168 }
1169 x->props.aalgo = orig->props.aalgo;
1170
ee5c2317
SK
1171 if (orig->aead) {
1172 x->aead = xfrm_algo_aead_clone(orig->aead);
1173 if (!x->aead)
1174 goto error;
1175 }
80c9abaa
SS
1176 if (orig->ealg) {
1177 x->ealg = xfrm_algo_clone(orig->ealg);
1178 if (!x->ealg)
1179 goto error;
1180 }
1181 x->props.ealgo = orig->props.ealgo;
1182
1183 if (orig->calg) {
1184 x->calg = xfrm_algo_clone(orig->calg);
1185 if (!x->calg)
1186 goto error;
1187 }
1188 x->props.calgo = orig->props.calgo;
1189
a716c119 1190 if (orig->encap) {
80c9abaa
SS
1191 x->encap = kmemdup(orig->encap, sizeof(*x->encap), GFP_KERNEL);
1192 if (!x->encap)
1193 goto error;
1194 }
1195
1196 if (orig->coaddr) {
1197 x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
1198 GFP_KERNEL);
1199 if (!x->coaddr)
1200 goto error;
1201 }
1202
af2f464e 1203 if (orig->replay_esn) {
cc9ab60e 1204 if (xfrm_replay_clone(x, orig))
af2f464e
SK
1205 goto error;
1206 }
1207
bd55775c
JHS
1208 memcpy(&x->mark, &orig->mark, sizeof(x->mark));
1209
cc9ab60e 1210 if (xfrm_init_state(x) < 0)
80c9abaa
SS
1211 goto error;
1212
1213 x->props.flags = orig->props.flags;
a947b0a9 1214 x->props.extra_flags = orig->props.extra_flags;
80c9abaa 1215
ee5c2317
SK
1216 x->tfcpad = orig->tfcpad;
1217 x->replay_maxdiff = orig->replay_maxdiff;
1218 x->replay_maxage = orig->replay_maxage;
80c9abaa
SS
1219 x->curlft.add_time = orig->curlft.add_time;
1220 x->km.state = orig->km.state;
1221 x->km.seq = orig->km.seq;
1222
1223 return x;
1224
1225 error:
553f9118
HX
1226 xfrm_state_put(x);
1227out:
80c9abaa
SS
1228 return NULL;
1229}
80c9abaa 1230
283bc9f3 1231struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
80c9abaa
SS
1232{
1233 unsigned int h;
8c0cba22
SK
1234 struct xfrm_state *x = NULL;
1235
1236 spin_lock_bh(&net->xfrm.xfrm_state_lock);
80c9abaa
SS
1237
1238 if (m->reqid) {
283bc9f3 1239 h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr,
80c9abaa 1240 m->reqid, m->old_family);
283bc9f3 1241 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
80c9abaa
SS
1242 if (x->props.mode != m->mode ||
1243 x->id.proto != m->proto)
1244 continue;
1245 if (m->reqid && x->props.reqid != m->reqid)
1246 continue;
70e94e66
YH
1247 if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
1248 m->old_family) ||
1249 !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
1250 m->old_family))
80c9abaa
SS
1251 continue;
1252 xfrm_state_hold(x);
8c0cba22 1253 break;
80c9abaa
SS
1254 }
1255 } else {
283bc9f3 1256 h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr,
80c9abaa 1257 m->old_family);
283bc9f3 1258 hlist_for_each_entry(x, net->xfrm.state_bysrc+h, bysrc) {
80c9abaa
SS
1259 if (x->props.mode != m->mode ||
1260 x->id.proto != m->proto)
1261 continue;
70e94e66
YH
1262 if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
1263 m->old_family) ||
1264 !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
1265 m->old_family))
80c9abaa
SS
1266 continue;
1267 xfrm_state_hold(x);
8c0cba22 1268 break;
80c9abaa
SS
1269 }
1270 }
1271
8c0cba22
SK
1272 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1273
1274 return x;
80c9abaa
SS
1275}
1276EXPORT_SYMBOL(xfrm_migrate_state_find);
1277
3e94c2dc
WC
1278struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
1279 struct xfrm_migrate *m)
80c9abaa
SS
1280{
1281 struct xfrm_state *xc;
80c9abaa 1282
cc9ab60e 1283 xc = xfrm_state_clone(x);
80c9abaa
SS
1284 if (!xc)
1285 return NULL;
1286
1287 memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr));
1288 memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr));
1289
1290 /* add state */
70e94e66 1291 if (xfrm_addr_equal(&x->id.daddr, &m->new_daddr, m->new_family)) {
80c9abaa
SS
1292 /* a care is needed when the destination address of the
1293 state is to be updated as it is a part of triplet */
1294 xfrm_state_insert(xc);
1295 } else {
cc9ab60e 1296 if (xfrm_state_add(xc) < 0)
80c9abaa
SS
1297 goto error;
1298 }
1299
1300 return xc;
1301error:
78347c8c 1302 xfrm_state_put(xc);
80c9abaa
SS
1303 return NULL;
1304}
1305EXPORT_SYMBOL(xfrm_state_migrate);
1306#endif
1307
1da177e4
LT
1308int xfrm_state_update(struct xfrm_state *x)
1309{
37b08e34 1310 struct xfrm_state *x1, *to_put;
1da177e4 1311 int err;
eb2971b6 1312 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
283bc9f3 1313 struct net *net = xs_net(x);
1da177e4 1314
37b08e34
DM
1315 to_put = NULL;
1316
283bc9f3 1317 spin_lock_bh(&net->xfrm.xfrm_state_lock);
edcd5821 1318 x1 = __xfrm_state_locate(x, use_spi, x->props.family);
1da177e4
LT
1319
1320 err = -ESRCH;
1321 if (!x1)
1322 goto out;
1323
1324 if (xfrm_state_kern(x1)) {
37b08e34 1325 to_put = x1;
1da177e4
LT
1326 err = -EEXIST;
1327 goto out;
1328 }
1329
1330 if (x1->km.state == XFRM_STATE_ACQ) {
1331 __xfrm_state_insert(x);
1332 x = NULL;
1333 }
1334 err = 0;
1335
1336out:
283bc9f3 1337 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4 1338
37b08e34
DM
1339 if (to_put)
1340 xfrm_state_put(to_put);
1341
1da177e4
LT
1342 if (err)
1343 return err;
1344
1345 if (!x) {
1346 xfrm_state_delete(x1);
1347 xfrm_state_put(x1);
1348 return 0;
1349 }
1350
1351 err = -EINVAL;
1352 spin_lock_bh(&x1->lock);
1353 if (likely(x1->km.state == XFRM_STATE_VALID)) {
1354 if (x->encap && x1->encap)
1355 memcpy(x1->encap, x->encap, sizeof(*x1->encap));
060f02a3
NT
1356 if (x->coaddr && x1->coaddr) {
1357 memcpy(x1->coaddr, x->coaddr, sizeof(*x1->coaddr));
1358 }
1359 if (!use_spi && memcmp(&x1->sel, &x->sel, sizeof(x1->sel)))
1360 memcpy(&x1->sel, &x->sel, sizeof(x1->sel));
1da177e4
LT
1361 memcpy(&x1->lft, &x->lft, sizeof(x1->lft));
1362 x1->km.dying = 0;
1363
9e0d57fd 1364 tasklet_hrtimer_start(&x1->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL);
1da177e4
LT
1365 if (x1->curlft.use_time)
1366 xfrm_state_check_expire(x1);
1367
1368 err = 0;
8fcbc637
TG
1369 x->km.state = XFRM_STATE_DEAD;
1370 __xfrm_state_put(x);
1da177e4
LT
1371 }
1372 spin_unlock_bh(&x1->lock);
1373
1374 xfrm_state_put(x1);
1375
1376 return err;
1377}
1378EXPORT_SYMBOL(xfrm_state_update);
1379
1380int xfrm_state_check_expire(struct xfrm_state *x)
1381{
1382 if (!x->curlft.use_time)
9d729f72 1383 x->curlft.use_time = get_seconds();
1da177e4 1384
1da177e4
LT
1385 if (x->curlft.bytes >= x->lft.hard_byte_limit ||
1386 x->curlft.packets >= x->lft.hard_packet_limit) {
4666faab 1387 x->km.state = XFRM_STATE_EXPIRED;
9b7a787d 1388 tasklet_hrtimer_start(&x->mtimer, ktime_set(0, 0), HRTIMER_MODE_REL);
1da177e4
LT
1389 return -EINVAL;
1390 }
1391
1392 if (!x->km.dying &&
1393 (x->curlft.bytes >= x->lft.soft_byte_limit ||
4666faab
HX
1394 x->curlft.packets >= x->lft.soft_packet_limit)) {
1395 x->km.dying = 1;
53bc6b4d 1396 km_state_expired(x, 0, 0);
4666faab 1397 }
1da177e4
LT
1398 return 0;
1399}
1400EXPORT_SYMBOL(xfrm_state_check_expire);
1401
1da177e4 1402struct xfrm_state *
a70486f0 1403xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi,
bd55775c 1404 u8 proto, unsigned short family)
1da177e4
LT
1405{
1406 struct xfrm_state *x;
1da177e4 1407
283bc9f3 1408 spin_lock_bh(&net->xfrm.xfrm_state_lock);
bd55775c 1409 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
283bc9f3 1410 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4
LT
1411 return x;
1412}
1413EXPORT_SYMBOL(xfrm_state_lookup);
1414
1415struct xfrm_state *
bd55775c 1416xfrm_state_lookup_byaddr(struct net *net, u32 mark,
a70486f0 1417 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
eb2971b6
MN
1418 u8 proto, unsigned short family)
1419{
1420 struct xfrm_state *x;
eb2971b6 1421
283bc9f3 1422 spin_lock_bh(&net->xfrm.xfrm_state_lock);
bd55775c 1423 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
283bc9f3 1424 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
eb2971b6
MN
1425 return x;
1426}
1427EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
1428
1429struct xfrm_state *
e473fcb4
MK
1430xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, u8 mode, u32 reqid,
1431 u8 proto, const xfrm_address_t *daddr,
1432 const xfrm_address_t *saddr, int create, unsigned short family)
1da177e4
LT
1433{
1434 struct xfrm_state *x;
1da177e4 1435
283bc9f3 1436 spin_lock_bh(&net->xfrm.xfrm_state_lock);
bd55775c 1437 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
283bc9f3 1438 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
2770834c 1439
1da177e4
LT
1440 return x;
1441}
1442EXPORT_SYMBOL(xfrm_find_acq);
1443
41a49cc3
MN
1444#ifdef CONFIG_XFRM_SUB_POLICY
1445int
1446xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
283bc9f3 1447 unsigned short family, struct net *net)
41a49cc3
MN
1448{
1449 int err = 0;
1450 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1451 if (!afinfo)
1452 return -EAFNOSUPPORT;
1453
283bc9f3 1454 spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/
41a49cc3
MN
1455 if (afinfo->tmpl_sort)
1456 err = afinfo->tmpl_sort(dst, src, n);
283bc9f3 1457 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
41a49cc3
MN
1458 xfrm_state_put_afinfo(afinfo);
1459 return err;
1460}
1461EXPORT_SYMBOL(xfrm_tmpl_sort);
1462
1463int
1464xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1465 unsigned short family)
1466{
1467 int err = 0;
1468 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
35ea790d 1469 struct net *net = xs_net(*src);
283bc9f3 1470
41a49cc3
MN
1471 if (!afinfo)
1472 return -EAFNOSUPPORT;
1473
283bc9f3 1474 spin_lock_bh(&net->xfrm.xfrm_state_lock);
41a49cc3
MN
1475 if (afinfo->state_sort)
1476 err = afinfo->state_sort(dst, src, n);
283bc9f3 1477 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
41a49cc3
MN
1478 xfrm_state_put_afinfo(afinfo);
1479 return err;
1480}
1481EXPORT_SYMBOL(xfrm_state_sort);
1482#endif
1483
1da177e4
LT
1484/* Silly enough, but I'm lazy to build resolution list */
1485
bd55775c 1486static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1da177e4
LT
1487{
1488 int i;
1da177e4 1489
5447c5e4 1490 for (i = 0; i <= net->xfrm.state_hmask; i++) {
8f126e37
DM
1491 struct xfrm_state *x;
1492
b67bfe0d 1493 hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) {
8f126e37 1494 if (x->km.seq == seq &&
3d6acfa7 1495 (mark & x->mark.m) == x->mark.v &&
8f126e37 1496 x->km.state == XFRM_STATE_ACQ) {
1da177e4
LT
1497 xfrm_state_hold(x);
1498 return x;
1499 }
1500 }
1501 }
1502 return NULL;
1503}
1504
bd55775c 1505struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1da177e4
LT
1506{
1507 struct xfrm_state *x;
1508
283bc9f3 1509 spin_lock_bh(&net->xfrm.xfrm_state_lock);
bd55775c 1510 x = __xfrm_find_acq_byseq(net, mark, seq);
283bc9f3 1511 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4
LT
1512 return x;
1513}
1514EXPORT_SYMBOL(xfrm_find_acq_byseq);
1515
1516u32 xfrm_get_acqseq(void)
1517{
1518 u32 res;
6836b9bd 1519 static atomic_t acqseq;
1520
1521 do {
1522 res = atomic_inc_return(&acqseq);
1523 } while (!res);
1da177e4 1524
1da177e4
LT
1525 return res;
1526}
1527EXPORT_SYMBOL(xfrm_get_acqseq);
1528
776e9dd9
FD
1529int verify_spi_info(u8 proto, u32 min, u32 max)
1530{
1531 switch (proto) {
1532 case IPPROTO_AH:
1533 case IPPROTO_ESP:
1534 break;
1535
1536 case IPPROTO_COMP:
1537 /* IPCOMP spi is 16-bits. */
1538 if (max >= 0x10000)
1539 return -EINVAL;
1540 break;
1541
1542 default:
1543 return -EINVAL;
1544 }
1545
1546 if (min > max)
1547 return -EINVAL;
1548
1549 return 0;
1550}
1551EXPORT_SYMBOL(verify_spi_info);
1552
658b219e 1553int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1da177e4 1554{
221df1ed 1555 struct net *net = xs_net(x);
f034b5d4 1556 unsigned int h;
1da177e4 1557 struct xfrm_state *x0;
658b219e
HX
1558 int err = -ENOENT;
1559 __be32 minspi = htonl(low);
1560 __be32 maxspi = htonl(high);
bd55775c 1561 u32 mark = x->mark.v & x->mark.m;
1da177e4 1562
658b219e
HX
1563 spin_lock_bh(&x->lock);
1564 if (x->km.state == XFRM_STATE_DEAD)
1565 goto unlock;
1566
1567 err = 0;
1da177e4 1568 if (x->id.spi)
658b219e
HX
1569 goto unlock;
1570
1571 err = -ENOENT;
1da177e4
LT
1572
1573 if (minspi == maxspi) {
bd55775c 1574 x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
1da177e4
LT
1575 if (x0) {
1576 xfrm_state_put(x0);
658b219e 1577 goto unlock;
1da177e4
LT
1578 }
1579 x->id.spi = minspi;
1580 } else {
1581 u32 spi = 0;
9b7a787d 1582 for (h = 0; h < high-low+1; h++) {
63862b5b 1583 spi = low + prandom_u32()%(high-low+1);
bd55775c 1584 x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
1da177e4
LT
1585 if (x0 == NULL) {
1586 x->id.spi = htonl(spi);
1587 break;
1588 }
1589 xfrm_state_put(x0);
1590 }
1591 }
1592 if (x->id.spi) {
283bc9f3 1593 spin_lock_bh(&net->xfrm.xfrm_state_lock);
12604d8a 1594 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
ae3fb6d3 1595 hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
283bc9f3 1596 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
658b219e
HX
1597
1598 err = 0;
1da177e4 1599 }
658b219e
HX
1600
1601unlock:
1602 spin_unlock_bh(&x->lock);
1603
1604 return err;
1da177e4
LT
1605}
1606EXPORT_SYMBOL(xfrm_alloc_spi);
1607
d3623099 1608static bool __xfrm_state_filter_match(struct xfrm_state *x,
870a2df4 1609 struct xfrm_address_filter *filter)
d3623099
ND
1610{
1611 if (filter) {
1612 if ((filter->family == AF_INET ||
1613 filter->family == AF_INET6) &&
1614 x->props.family != filter->family)
1615 return false;
1616
1617 return addr_match(&x->props.saddr, &filter->saddr,
1618 filter->splen) &&
1619 addr_match(&x->id.daddr, &filter->daddr,
1620 filter->dplen);
1621 }
1622 return true;
1623}
1624
284fa7da 1625int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
4c563f76 1626 int (*func)(struct xfrm_state *, int, void*),
1da177e4
LT
1627 void *data)
1628{
12a169e7
HX
1629 struct xfrm_state *state;
1630 struct xfrm_state_walk *x;
1da177e4
LT
1631 int err = 0;
1632
12a169e7 1633 if (walk->seq != 0 && list_empty(&walk->all))
4c563f76
TT
1634 return 0;
1635
283bc9f3 1636 spin_lock_bh(&net->xfrm.xfrm_state_lock);
12a169e7 1637 if (list_empty(&walk->all))
284fa7da 1638 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
12a169e7 1639 else
80077702 1640 x = list_first_entry(&walk->all, struct xfrm_state_walk, all);
284fa7da 1641 list_for_each_entry_from(x, &net->xfrm.state_all, all) {
12a169e7 1642 if (x->state == XFRM_STATE_DEAD)
4c563f76 1643 continue;
12a169e7
HX
1644 state = container_of(x, struct xfrm_state, km);
1645 if (!xfrm_id_proto_match(state->id.proto, walk->proto))
4c563f76 1646 continue;
d3623099
ND
1647 if (!__xfrm_state_filter_match(state, walk->filter))
1648 continue;
12a169e7
HX
1649 err = func(state, walk->seq, data);
1650 if (err) {
1651 list_move_tail(&walk->all, &x->all);
1652 goto out;
1da177e4 1653 }
12a169e7 1654 walk->seq++;
1da177e4 1655 }
12a169e7 1656 if (walk->seq == 0) {
1da177e4
LT
1657 err = -ENOENT;
1658 goto out;
1659 }
12a169e7 1660 list_del_init(&walk->all);
1da177e4 1661out:
283bc9f3 1662 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1da177e4
LT
1663 return err;
1664}
1665EXPORT_SYMBOL(xfrm_state_walk);
1666
d3623099 1667void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
870a2df4 1668 struct xfrm_address_filter *filter)
5c182458 1669{
12a169e7 1670 INIT_LIST_HEAD(&walk->all);
5c182458 1671 walk->proto = proto;
12a169e7
HX
1672 walk->state = XFRM_STATE_DEAD;
1673 walk->seq = 0;
d3623099 1674 walk->filter = filter;
5c182458
HX
1675}
1676EXPORT_SYMBOL(xfrm_state_walk_init);
1677
283bc9f3 1678void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net)
abb81c4f 1679{
d3623099
ND
1680 kfree(walk->filter);
1681
12a169e7 1682 if (list_empty(&walk->all))
5c182458 1683 return;
5c182458 1684
283bc9f3 1685 spin_lock_bh(&net->xfrm.xfrm_state_lock);
12a169e7 1686 list_del(&walk->all);
283bc9f3 1687 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
abb81c4f
HX
1688}
1689EXPORT_SYMBOL(xfrm_state_walk_done);
1690
f8cd5488
JHS
1691static void xfrm_replay_timer_handler(unsigned long data)
1692{
3e94c2dc 1693 struct xfrm_state *x = (struct xfrm_state *)data;
f8cd5488
JHS
1694
1695 spin_lock(&x->lock);
1696
2717096a 1697 if (x->km.state == XFRM_STATE_VALID) {
a6483b79 1698 if (xfrm_aevent_is_on(xs_net(x)))
9fdc4883 1699 x->repl->notify(x, XFRM_REPLAY_TIMEOUT);
2717096a
JHS
1700 else
1701 x->xflags |= XFRM_TIME_DEFER;
1702 }
f8cd5488
JHS
1703
1704 spin_unlock(&x->lock);
1705}
1706
df01812e 1707static LIST_HEAD(xfrm_km_list);
1da177e4 1708
214e005b 1709void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c)
1da177e4
LT
1710{
1711 struct xfrm_mgr *km;
1712
85168c00
CW
1713 rcu_read_lock();
1714 list_for_each_entry_rcu(km, &xfrm_km_list, list)
26b15dad
JHS
1715 if (km->notify_policy)
1716 km->notify_policy(xp, dir, c);
85168c00 1717 rcu_read_unlock();
26b15dad 1718}
1da177e4 1719
214e005b 1720void km_state_notify(struct xfrm_state *x, const struct km_event *c)
26b15dad
JHS
1721{
1722 struct xfrm_mgr *km;
85168c00
CW
1723 rcu_read_lock();
1724 list_for_each_entry_rcu(km, &xfrm_km_list, list)
26b15dad
JHS
1725 if (km->notify)
1726 km->notify(x, c);
85168c00 1727 rcu_read_unlock();
26b15dad
JHS
1728}
1729
1730EXPORT_SYMBOL(km_policy_notify);
1731EXPORT_SYMBOL(km_state_notify);
1732
15e47304 1733void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
26b15dad
JHS
1734{
1735 struct km_event c;
1736
bf08867f 1737 c.data.hard = hard;
15e47304 1738 c.portid = portid;
f60f6b8f 1739 c.event = XFRM_MSG_EXPIRE;
26b15dad 1740 km_state_notify(x, &c);
1da177e4
LT
1741}
1742
53bc6b4d 1743EXPORT_SYMBOL(km_state_expired);
26b15dad
JHS
1744/*
1745 * We send to all registered managers regardless of failure
1746 * We are happy with one success
1747*/
980ebd25 1748int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
1da177e4 1749{
26b15dad 1750 int err = -EINVAL, acqret;
1da177e4
LT
1751 struct xfrm_mgr *km;
1752
85168c00
CW
1753 rcu_read_lock();
1754 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
65e0736b 1755 acqret = km->acquire(x, t, pol);
26b15dad
JHS
1756 if (!acqret)
1757 err = acqret;
1da177e4 1758 }
85168c00 1759 rcu_read_unlock();
1da177e4
LT
1760 return err;
1761}
980ebd25 1762EXPORT_SYMBOL(km_query);
1da177e4 1763
5d36b180 1764int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
1da177e4
LT
1765{
1766 int err = -EINVAL;
1767 struct xfrm_mgr *km;
1768
85168c00
CW
1769 rcu_read_lock();
1770 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1da177e4
LT
1771 if (km->new_mapping)
1772 err = km->new_mapping(x, ipaddr, sport);
1773 if (!err)
1774 break;
1775 }
85168c00 1776 rcu_read_unlock();
1da177e4
LT
1777 return err;
1778}
1779EXPORT_SYMBOL(km_new_mapping);
1780
15e47304 1781void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
1da177e4 1782{
26b15dad 1783 struct km_event c;
1da177e4 1784
bf08867f 1785 c.data.hard = hard;
15e47304 1786 c.portid = portid;
f60f6b8f 1787 c.event = XFRM_MSG_POLEXPIRE;
26b15dad 1788 km_policy_notify(pol, dir, &c);
1da177e4 1789}
a70fcb0b 1790EXPORT_SYMBOL(km_policy_expired);
1da177e4 1791
2d60abc2 1792#ifdef CONFIG_XFRM_MIGRATE
183cad12
DM
1793int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1794 const struct xfrm_migrate *m, int num_migrate,
1795 const struct xfrm_kmaddress *k)
80c9abaa
SS
1796{
1797 int err = -EINVAL;
1798 int ret;
1799 struct xfrm_mgr *km;
1800
85168c00
CW
1801 rcu_read_lock();
1802 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
80c9abaa 1803 if (km->migrate) {
13c1d189 1804 ret = km->migrate(sel, dir, type, m, num_migrate, k);
80c9abaa
SS
1805 if (!ret)
1806 err = ret;
1807 }
1808 }
85168c00 1809 rcu_read_unlock();
80c9abaa
SS
1810 return err;
1811}
1812EXPORT_SYMBOL(km_migrate);
2d60abc2 1813#endif
80c9abaa 1814
db983c11 1815int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr)
97a64b45
MN
1816{
1817 int err = -EINVAL;
1818 int ret;
1819 struct xfrm_mgr *km;
1820
85168c00
CW
1821 rcu_read_lock();
1822 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
97a64b45 1823 if (km->report) {
db983c11 1824 ret = km->report(net, proto, sel, addr);
97a64b45
MN
1825 if (!ret)
1826 err = ret;
1827 }
1828 }
85168c00 1829 rcu_read_unlock();
97a64b45
MN
1830 return err;
1831}
1832EXPORT_SYMBOL(km_report);
1833
0f24558e
HG
1834bool km_is_alive(const struct km_event *c)
1835{
1836 struct xfrm_mgr *km;
1837 bool is_alive = false;
1838
1839 rcu_read_lock();
1840 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1841 if (km->is_alive && km->is_alive(c)) {
1842 is_alive = true;
1843 break;
1844 }
1845 }
1846 rcu_read_unlock();
1847
1848 return is_alive;
1849}
1850EXPORT_SYMBOL(km_is_alive);
1851
1da177e4
LT
1852int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
1853{
1854 int err;
1855 u8 *data;
1856 struct xfrm_mgr *km;
1857 struct xfrm_policy *pol = NULL;
1858
1859 if (optlen <= 0 || optlen > PAGE_SIZE)
1860 return -EMSGSIZE;
1861
1862 data = kmalloc(optlen, GFP_KERNEL);
1863 if (!data)
1864 return -ENOMEM;
1865
1866 err = -EFAULT;
1867 if (copy_from_user(data, optval, optlen))
1868 goto out;
1869
1870 err = -EINVAL;
85168c00
CW
1871 rcu_read_lock();
1872 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
cb969f07 1873 pol = km->compile_policy(sk, optname, data,
1da177e4
LT
1874 optlen, &err);
1875 if (err >= 0)
1876 break;
1877 }
85168c00 1878 rcu_read_unlock();
1da177e4
LT
1879
1880 if (err >= 0) {
1881 xfrm_sk_policy_insert(sk, err, pol);
1882 xfrm_pol_put(pol);
1883 err = 0;
1884 }
1885
1886out:
1887 kfree(data);
1888 return err;
1889}
1890EXPORT_SYMBOL(xfrm_user_policy);
1891
85168c00
CW
1892static DEFINE_SPINLOCK(xfrm_km_lock);
1893
1da177e4
LT
1894int xfrm_register_km(struct xfrm_mgr *km)
1895{
85168c00
CW
1896 spin_lock_bh(&xfrm_km_lock);
1897 list_add_tail_rcu(&km->list, &xfrm_km_list);
1898 spin_unlock_bh(&xfrm_km_lock);
1da177e4
LT
1899 return 0;
1900}
1901EXPORT_SYMBOL(xfrm_register_km);
1902
1903int xfrm_unregister_km(struct xfrm_mgr *km)
1904{
85168c00
CW
1905 spin_lock_bh(&xfrm_km_lock);
1906 list_del_rcu(&km->list);
1907 spin_unlock_bh(&xfrm_km_lock);
1908 synchronize_rcu();
1da177e4
LT
1909 return 0;
1910}
1911EXPORT_SYMBOL(xfrm_unregister_km);
1912
1913int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
1914{
1915 int err = 0;
1916 if (unlikely(afinfo == NULL))
1917 return -EINVAL;
1918 if (unlikely(afinfo->family >= NPROTO))
1919 return -EAFNOSUPPORT;
44abdc30 1920 spin_lock_bh(&xfrm_state_afinfo_lock);
1da177e4 1921 if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
f31e8d4f 1922 err = -EEXIST;
edcd5821 1923 else
44abdc30
CW
1924 rcu_assign_pointer(xfrm_state_afinfo[afinfo->family], afinfo);
1925 spin_unlock_bh(&xfrm_state_afinfo_lock);
1da177e4
LT
1926 return err;
1927}
1928EXPORT_SYMBOL(xfrm_state_register_afinfo);
1929
1930int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
1931{
1932 int err = 0;
1933 if (unlikely(afinfo == NULL))
1934 return -EINVAL;
1935 if (unlikely(afinfo->family >= NPROTO))
1936 return -EAFNOSUPPORT;
44abdc30 1937 spin_lock_bh(&xfrm_state_afinfo_lock);
1da177e4
LT
1938 if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
1939 if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
1940 err = -EINVAL;
edcd5821 1941 else
44abdc30 1942 RCU_INIT_POINTER(xfrm_state_afinfo[afinfo->family], NULL);
1da177e4 1943 }
44abdc30
CW
1944 spin_unlock_bh(&xfrm_state_afinfo_lock);
1945 synchronize_rcu();
1da177e4
LT
1946 return err;
1947}
1948EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
1949
628e341f 1950struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
1da177e4
LT
1951{
1952 struct xfrm_state_afinfo *afinfo;
1953 if (unlikely(family >= NPROTO))
1954 return NULL;
44abdc30
CW
1955 rcu_read_lock();
1956 afinfo = rcu_dereference(xfrm_state_afinfo[family]);
546be240 1957 if (unlikely(!afinfo))
44abdc30 1958 rcu_read_unlock();
1da177e4
LT
1959 return afinfo;
1960}
1961
628e341f 1962void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
1da177e4 1963{
44abdc30 1964 rcu_read_unlock();
1da177e4
LT
1965}
1966
1967/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
1968void xfrm_state_delete_tunnel(struct xfrm_state *x)
1969{
1970 if (x->tunnel) {
1971 struct xfrm_state *t = x->tunnel;
1972
1973 if (atomic_read(&t->tunnel_users) == 2)
1974 xfrm_state_delete(t);
1975 atomic_dec(&t->tunnel_users);
1976 xfrm_state_put(t);
1977 x->tunnel = NULL;
1978 }
1979}
1980EXPORT_SYMBOL(xfrm_state_delete_tunnel);
1981
1982int xfrm_state_mtu(struct xfrm_state *x, int mtu)
1983{
c5c25238 1984 int res;
1da177e4 1985
c5c25238
PM
1986 spin_lock_bh(&x->lock);
1987 if (x->km.state == XFRM_STATE_VALID &&
1988 x->type && x->type->get_mtu)
1989 res = x->type->get_mtu(x, mtu);
1990 else
28121617 1991 res = mtu - x->props.header_len;
c5c25238 1992 spin_unlock_bh(&x->lock);
1da177e4
LT
1993 return res;
1994}
1995
a454f0cc 1996int __xfrm_init_state(struct xfrm_state *x, bool init_replay)
72cb6962 1997{
d094cd83 1998 struct xfrm_state_afinfo *afinfo;
df9dcb45 1999 struct xfrm_mode *inner_mode;
d094cd83 2000 int family = x->props.family;
72cb6962
HX
2001 int err;
2002
d094cd83
HX
2003 err = -EAFNOSUPPORT;
2004 afinfo = xfrm_state_get_afinfo(family);
2005 if (!afinfo)
2006 goto error;
2007
2008 err = 0;
2009 if (afinfo->init_flags)
2010 err = afinfo->init_flags(x);
2011
2012 xfrm_state_put_afinfo(afinfo);
2013
2014 if (err)
2015 goto error;
2016
2017 err = -EPROTONOSUPPORT;
13996378 2018
df9dcb45
KM
2019 if (x->sel.family != AF_UNSPEC) {
2020 inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
2021 if (inner_mode == NULL)
2022 goto error;
2023
2024 if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
2025 family != x->sel.family) {
2026 xfrm_put_mode(inner_mode);
2027 goto error;
2028 }
2029
2030 x->inner_mode = inner_mode;
2031 } else {
2032 struct xfrm_mode *inner_mode_iaf;
d81d2285 2033 int iafamily = AF_INET;
df9dcb45 2034
d81d2285 2035 inner_mode = xfrm_get_mode(x->props.mode, x->props.family);
df9dcb45
KM
2036 if (inner_mode == NULL)
2037 goto error;
2038
2039 if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) {
2040 xfrm_put_mode(inner_mode);
2041 goto error;
2042 }
d81d2285 2043 x->inner_mode = inner_mode;
df9dcb45 2044
d81d2285
MW
2045 if (x->props.family == AF_INET)
2046 iafamily = AF_INET6;
df9dcb45 2047
d81d2285
MW
2048 inner_mode_iaf = xfrm_get_mode(x->props.mode, iafamily);
2049 if (inner_mode_iaf) {
2050 if (inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL)
2051 x->inner_mode_iaf = inner_mode_iaf;
2052 else
2053 xfrm_put_mode(inner_mode_iaf);
df9dcb45
KM
2054 }
2055 }
13996378 2056
d094cd83 2057 x->type = xfrm_get_type(x->id.proto, family);
72cb6962
HX
2058 if (x->type == NULL)
2059 goto error;
2060
2061 err = x->type->init_state(x);
2062 if (err)
2063 goto error;
2064
13996378 2065 x->outer_mode = xfrm_get_mode(x->props.mode, family);
599901c3
JL
2066 if (x->outer_mode == NULL) {
2067 err = -EPROTONOSUPPORT;
b59f45d0 2068 goto error;
599901c3 2069 }
b59f45d0 2070
a454f0cc
WY
2071 if (init_replay) {
2072 err = xfrm_init_replay(x);
2073 if (err)
2074 goto error;
2075 }
2076
72cb6962
HX
2077 x->km.state = XFRM_STATE_VALID;
2078
2079error:
2080 return err;
2081}
2082
a454f0cc
WY
2083EXPORT_SYMBOL(__xfrm_init_state);
2084
2085int xfrm_init_state(struct xfrm_state *x)
2086{
2087 return __xfrm_init_state(x, true);
2088}
2089
72cb6962 2090EXPORT_SYMBOL(xfrm_init_state);
a716c119 2091
d62ddc21 2092int __net_init xfrm_state_init(struct net *net)
1da177e4 2093{
f034b5d4
DM
2094 unsigned int sz;
2095
9d4139c7
AD
2096 INIT_LIST_HEAD(&net->xfrm.state_all);
2097
f034b5d4
DM
2098 sz = sizeof(struct hlist_head) * 8;
2099
73d189dc
AD
2100 net->xfrm.state_bydst = xfrm_hash_alloc(sz);
2101 if (!net->xfrm.state_bydst)
2102 goto out_bydst;
d320bbb3
AD
2103 net->xfrm.state_bysrc = xfrm_hash_alloc(sz);
2104 if (!net->xfrm.state_bysrc)
2105 goto out_bysrc;
b754a4fd
AD
2106 net->xfrm.state_byspi = xfrm_hash_alloc(sz);
2107 if (!net->xfrm.state_byspi)
2108 goto out_byspi;
529983ec 2109 net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
1da177e4 2110
0bf7c5b0 2111 net->xfrm.state_num = 0;
63082733 2112 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
b8a0ae20 2113 INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
c7837144 2114 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
283bc9f3 2115 spin_lock_init(&net->xfrm.xfrm_state_lock);
d62ddc21 2116 return 0;
73d189dc 2117
b754a4fd
AD
2118out_byspi:
2119 xfrm_hash_free(net->xfrm.state_bysrc, sz);
d320bbb3
AD
2120out_bysrc:
2121 xfrm_hash_free(net->xfrm.state_bydst, sz);
73d189dc
AD
2122out_bydst:
2123 return -ENOMEM;
d62ddc21
AD
2124}
2125
2126void xfrm_state_fini(struct net *net)
2127{
73d189dc
AD
2128 unsigned int sz;
2129
7c2776ee 2130 flush_work(&net->xfrm.state_hash_work);
2e71029e 2131 xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
7c2776ee
AD
2132 flush_work(&net->xfrm.state_gc_work);
2133
9d4139c7 2134 WARN_ON(!list_empty(&net->xfrm.state_all));
73d189dc 2135
529983ec 2136 sz = (net->xfrm.state_hmask + 1) * sizeof(struct hlist_head);
b754a4fd
AD
2137 WARN_ON(!hlist_empty(net->xfrm.state_byspi));
2138 xfrm_hash_free(net->xfrm.state_byspi, sz);
d320bbb3
AD
2139 WARN_ON(!hlist_empty(net->xfrm.state_bysrc));
2140 xfrm_hash_free(net->xfrm.state_bysrc, sz);
73d189dc
AD
2141 WARN_ON(!hlist_empty(net->xfrm.state_bydst));
2142 xfrm_hash_free(net->xfrm.state_bydst, sz);
1da177e4
LT
2143}
2144
ab5f5e8b 2145#ifdef CONFIG_AUDITSYSCALL
cf35f43e
IJ
2146static void xfrm_audit_helper_sainfo(struct xfrm_state *x,
2147 struct audit_buffer *audit_buf)
ab5f5e8b 2148{
68277acc
PM
2149 struct xfrm_sec_ctx *ctx = x->security;
2150 u32 spi = ntohl(x->id.spi);
2151
2152 if (ctx)
ab5f5e8b 2153 audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
68277acc 2154 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
ab5f5e8b 2155
9b7a787d 2156 switch (x->props.family) {
ab5f5e8b 2157 case AF_INET:
21454aaa
HH
2158 audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
2159 &x->props.saddr.a4, &x->id.daddr.a4);
ab5f5e8b
JL
2160 break;
2161 case AF_INET6:
5b095d98 2162 audit_log_format(audit_buf, " src=%pI6 dst=%pI6",
fdb46ee7 2163 x->props.saddr.a6, x->id.daddr.a6);
ab5f5e8b
JL
2164 break;
2165 }
68277acc
PM
2166
2167 audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
ab5f5e8b
JL
2168}
2169
cf35f43e
IJ
2170static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
2171 struct audit_buffer *audit_buf)
afeb14b4 2172{
b71d1d42
ED
2173 const struct iphdr *iph4;
2174 const struct ipv6hdr *iph6;
afeb14b4
PM
2175
2176 switch (family) {
2177 case AF_INET:
2178 iph4 = ip_hdr(skb);
21454aaa
HH
2179 audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
2180 &iph4->saddr, &iph4->daddr);
afeb14b4
PM
2181 break;
2182 case AF_INET6:
2183 iph6 = ipv6_hdr(skb);
2184 audit_log_format(audit_buf,
5b095d98 2185 " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x",
9b7a787d 2186 &iph6->saddr, &iph6->daddr,
afeb14b4
PM
2187 iph6->flow_lbl[0] & 0x0f,
2188 iph6->flow_lbl[1],
2189 iph6->flow_lbl[2]);
2190 break;
2191 }
2192}
2193
2e71029e 2194void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid)
ab5f5e8b
JL
2195{
2196 struct audit_buffer *audit_buf;
ab5f5e8b 2197
afeb14b4 2198 audit_buf = xfrm_audit_start("SAD-add");
ab5f5e8b
JL
2199 if (audit_buf == NULL)
2200 return;
2e71029e 2201 xfrm_audit_helper_usrinfo(task_valid, audit_buf);
afeb14b4
PM
2202 xfrm_audit_helper_sainfo(x, audit_buf);
2203 audit_log_format(audit_buf, " res=%u", result);
ab5f5e8b
JL
2204 audit_log_end(audit_buf);
2205}
2206EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
2207
2e71029e 2208void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid)
ab5f5e8b
JL
2209{
2210 struct audit_buffer *audit_buf;
ab5f5e8b 2211
afeb14b4 2212 audit_buf = xfrm_audit_start("SAD-delete");
ab5f5e8b
JL
2213 if (audit_buf == NULL)
2214 return;
2e71029e 2215 xfrm_audit_helper_usrinfo(task_valid, audit_buf);
afeb14b4
PM
2216 xfrm_audit_helper_sainfo(x, audit_buf);
2217 audit_log_format(audit_buf, " res=%u", result);
ab5f5e8b
JL
2218 audit_log_end(audit_buf);
2219}
2220EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
afeb14b4
PM
2221
2222void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
2223 struct sk_buff *skb)
2224{
2225 struct audit_buffer *audit_buf;
2226 u32 spi;
2227
2228 audit_buf = xfrm_audit_start("SA-replay-overflow");
2229 if (audit_buf == NULL)
2230 return;
2231 xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
2232 /* don't record the sequence number because it's inherent in this kind
2233 * of audit message */
2234 spi = ntohl(x->id.spi);
2235 audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
2236 audit_log_end(audit_buf);
2237}
2238EXPORT_SYMBOL_GPL(xfrm_audit_state_replay_overflow);
2239
9fdc4883 2240void xfrm_audit_state_replay(struct xfrm_state *x,
afeb14b4
PM
2241 struct sk_buff *skb, __be32 net_seq)
2242{
2243 struct audit_buffer *audit_buf;
2244 u32 spi;
2245
2246 audit_buf = xfrm_audit_start("SA-replayed-pkt");
2247 if (audit_buf == NULL)
2248 return;
2249 xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
2250 spi = ntohl(x->id.spi);
2251 audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
2252 spi, spi, ntohl(net_seq));
2253 audit_log_end(audit_buf);
2254}
9fdc4883 2255EXPORT_SYMBOL_GPL(xfrm_audit_state_replay);
afeb14b4
PM
2256
2257void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family)
2258{
2259 struct audit_buffer *audit_buf;
2260
2261 audit_buf = xfrm_audit_start("SA-notfound");
2262 if (audit_buf == NULL)
2263 return;
2264 xfrm_audit_helper_pktinfo(skb, family, audit_buf);
2265 audit_log_end(audit_buf);
2266}
2267EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound_simple);
2268
2269void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
2270 __be32 net_spi, __be32 net_seq)
2271{
2272 struct audit_buffer *audit_buf;
2273 u32 spi;
2274
2275 audit_buf = xfrm_audit_start("SA-notfound");
2276 if (audit_buf == NULL)
2277 return;
2278 xfrm_audit_helper_pktinfo(skb, family, audit_buf);
2279 spi = ntohl(net_spi);
2280 audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
2281 spi, spi, ntohl(net_seq));
2282 audit_log_end(audit_buf);
2283}
2284EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound);
2285
2286void xfrm_audit_state_icvfail(struct xfrm_state *x,
2287 struct sk_buff *skb, u8 proto)
2288{
2289 struct audit_buffer *audit_buf;
2290 __be32 net_spi;
2291 __be32 net_seq;
2292
2293 audit_buf = xfrm_audit_start("SA-icv-failure");
2294 if (audit_buf == NULL)
2295 return;
2296 xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
2297 if (xfrm_parse_spi(skb, proto, &net_spi, &net_seq) == 0) {
2298 u32 spi = ntohl(net_spi);
2299 audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
2300 spi, spi, ntohl(net_seq));
2301 }
2302 audit_log_end(audit_buf);
2303}
2304EXPORT_SYMBOL_GPL(xfrm_audit_state_icvfail);
ab5f5e8b 2305#endif /* CONFIG_AUDITSYSCALL */