aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorGao Pan <pandy.gao@nxp.com>2016-01-18 02:44:01 -0500
committerMark Brown <broonie@kernel.org>2016-01-22 11:46:58 -0500
commitf8efca2f1783050368c71e978ee32d3aa692637b (patch)
tree6b4032cdcd74759d85739bad456cd792c6ceebd0 /lib
parentcabeea980879c2c701b0bd03f145c9f7dae17a63 (diff)
spi: imx: fix spi resource leak with dma transfer
In spi_imx_dma_transfer(), when desc_rx = dmaengine_prep_slave_sg() fails, the context goes to label no_dma and then return. However, the memory allocated for desc_tx has not been freed yet, which leads to resource leak. Signed-off-by: Gao Pan <pandy.gao@nxp.com> Reviewed-by: Fugang Duan <B38611@freescale.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'lib')
0 files changed, 0 insertions, 0 deletions
committer David S. Miller <davem@davemloft.net> 2006-03-21 01:33:17 -0500 [NET] sem2mutex: net/' href='/cgit/cgit.cgi/litmus-rt-ext-res.git/commit/include/net/xfrm.h?id=4a3e2f711a00a1feb72ae12fdc749da10179d185'>4a3e2f711a00
ab5f5e8b144e
5a0e3ad6af86
1da177e4c3f4


436a0a402203
1da177e4c3f4


fe1a5f031e76
9e0d57fd6dad


558f82ef6e0d


1da177e4c3f4
d3d6dd3adaaa







fa9921e46fd5
1da177e4c3f4
b59f45d0b287

d3d6dd3adaaa

1da177e4c3f4
558f82ef6e0d
59c9940ed0ef
558f82ef6e0d
59c9940ed0ef
558f82ef6e0d

1da177e4c3f4





























































12a169e7d8f4


d3623099d350

12a169e7d8f4
870a2df4ca02
12a169e7d8f4

1da177e4c3f4
fd2c3ef761fb
0c5c9fb55106
abb81c4f3cb9
12a169e7d8f4
abb81c4f3cb9

8f126e37c0b2

1da177e4c3f4





bf825f81b454
35d2856b4693
1da177e4c3f4
9d4a706d8524

12a169e7d8f4

1da177e4c3f4











a947b0a93efa
1da177e4c3f4




4447bb33f094
1da177e4c3f4

1a6509d99122
69b0137f6164
1da177e4c3f4



060f02a3bdd4


1da177e4c3f4







9736acf395d3
1da177e4c3f4
f8cd54884e67

9736acf395d3
f8cd54884e67
9fdc4883d92d
e45a8a9e60ff
9fdc4883d92d
2717096ab41e




f8cd54884e67






1da177e4c3f4



9e0d57fd6dad
1da177e4c3f4
e3c0d0475075


9afaca057980
d26f39840031
9afaca057980
1da177e4c3f4

533cb5b0a63f
13996378e658
df9dcb4588ac
13996378e658
1da177e4c3f4
df71837d5024


1da177e4c3f4




673c09be457b




2717096ab41e

e3c0d0475075
2717096ab41e
1da177e4c3f4








26b15dad9f1c
fd2c3ef761fb
bf08867f91a4



f8cd54884e67
f7b6983f0fee
bf08867f91a4

26b15dad9f1c
15e473046cb6
26b15dad9f1c
7067802e2624
26b15dad9f1c

9fdc4883d92d




3b59df46a449


9fdc4883d92d



25ee3286dcbc
1da177e4c3f4



1da177e4c3f4
ddcfd79680c1
42a7b32b73d6

5e6b930f21b0

42a7b32b73d6


1da177e4c3f4
d5422efe680f

05d8402576c9
a1b051405bc1


25ee3286dcbc
87c1e12b5eeb
0c7b3eefb4ab
2774c131b1d1
1da177e4c3f4

d511337a1eda




1da177e4c3f4

d511337a1eda



53bc6b4d29c0
1da177e4c3f4
17c2a42a24e1
36cf9acf93e8
8e3d716cce0c
17c2a42a24e1
533cb5b0a63f
aa5d62cc8777
d094cd83c06e
73e5ebb20f28

19bd62441c36



41a49cc3c02a

ede2059dbaf9
7026b1ddb6b8
227620e29509

36cf9acf93e8

716062fd4c2f

628e341f319f
1da177e4c3f4

d511337a1eda



1da177e4c3f4
2f32b51b609f









d511337a1eda
1da177e4c3f4
fd2c3ef761fb
1da177e4c3f4

a63374631e71

1b5c229987dc
436a0a402203
f04e7e8d7f17

1da177e4c3f4
72cb6962a91f
1da177e4c3f4
e695633e21ff
1da177e4c3f4
8f029de281b2

aee5adb4307c
1da177e4c3f4
c5c252389374
1da177e4c3f4

d511337a1eda

1da177e4c3f4
b59f45d0b287
227620e29509




















b59f45d0b287
37fedd3aab65











36cf9acf93e8











b59f45d0b287
17c2a42a24e1
b59f45d0b287

1bfcb10f670f





b59f45d0b287

d511337a1eda

b59f45d0b287
df9dcb4588ac




















fd2c3ef761fb
1da177e4c3f4










76b3f055f389

a63374631e71
1da177e4c3f4
7e49e6de30ef
a63374631e71
1da177e4c3f4

a63374631e71
1da177e4c3f4

a63374631e71
1da177e4c3f4
c5d18e984a31
a63374631e71
c5d18e984a31
1da177e4c3f4
a63374631e71


1da177e4c3f4

622dc8281a80
1da177e4c3f4
12a169e7d8f4










a0073fe18e71





fd2c3ef761fb
0c5c9fb55106
2518c7c2b3d7

1da177e4c3f4





fe1a5f031e76
80c802f3073e
1da177e4c3f4

bf825f81b454
1da177e4c3f4


12a169e7d8f4
a0073fe18e71
46ca5f5dc4f1


46ca5f5dc4f1
12a169e7d8f4
df71837d5024
1da177e4c3f4
56f047305dd4
1da177e4c3f4

63eb23f5d80d
0331b1f383e1



13c1d18931eb






80c9abaabf42












f8cd54884e67
f8cd54884e67









1da177e4c3f4
fd2c3ef761fb
1da177e4c3f4

214e005bc32c
65e0736bc2ac
cb969f072b6d
5d36b1803d87
214e005bc32c
db983c114488
183cad12785f




0f24558e9156
1da177e4c3f4

d511337a1eda

1da177e4c3f4
70be6c91c865













436a0a402203





70be6c91c865
436a0a402203

b318e0e4ef4e
1ce3644ade9c







b318e0e4ef4e
436a0a402203



36cf9acf93e8




70be6c91c865
36cf9acf93e8




732c8bd59062


36cf9acf93e8








732c8bd59062


36cf9acf93e8





716062fd4c2f




70be6c91c865
716062fd4c2f
716062fd4c2f
2fcb45b6b879
716062fd4c2f



c9204d9ca79b
afeb14b49098
ab5f5e8b144e

ab5f5e8b144e
afeb14b49098

ab5f5e8b144e
afeb14b49098
ab5f5e8b144e

afeb14b49098


ab5f5e8b144e
2e71029e2c32
afeb14b49098

2e71029e2c32






f1370cc4a01e
ab5f5e8b144e

2e71029e2c32




d511337a1eda








c9204d9ca79b
41fef0ee7b8f

2e71029e2c32
41fef0ee7b8f



2e71029e2c32
41fef0ee7b8f



2e71029e2c32
41fef0ee7b8f



2e71029e2c32
41fef0ee7b8f







9fdc4883d92d




41fef0ee7b8f













c9204d9ca79b
161a09e737f0
1da177e4c3f4





d511337a1eda
1da177e4c3f4



64c31b3f7648
1da177e4c3f4

4e81bb8336a0





4e81bb8336a0
d511337a1eda
1da177e4c3f4
21380b81ef86




1da177e4c3f4










1744a8fe09e5

1da177e4c3f4
1744a8fe09e5

1da177e4c3f4


a63374631e71
1da177e4c3f4



1744a8fe09e5
1da177e4c3f4

5f19343fb196
1da177e4c3f4



1744a8fe09e5
1da177e4c3f4

1744a8fe09e5
1da177e4c3f4

26bff940dd97







1da177e4c3f4
6281dcc94a96
1da177e4c3f4
f9d07e41f89e
1d28f42c1bd4
1da177e4c3f4

ba4e58eca8aa
1da177e4c3f4
6281dcc94a96
1da177e4c3f4


6281dcc94a96
1da177e4c3f4
2ce4272a699c
6281dcc94a96
2ce4272a699c
cc9ff19da9bf
6281dcc94a96
cc9ff19da9bf
1da177e4c3f4






6281dcc94a96
1da177e4c3f4
f9d07e41f89e
1d28f42c1bd4
1da177e4c3f4

ba4e58eca8aa
1da177e4c3f4
6281dcc94a96
1da177e4c3f4


6281dcc94a96
1da177e4c3f4
cc9ff19da9bf
6281dcc94a96
cc9ff19da9bf
1da177e4c3f4





d511337a1eda

1da177e4c3f4
df71837d5024



bc9b35ad4138
df71837d5024







bc9b35ad4138
df71837d5024
bc9b35ad4138
df71837d5024


1da177e4c3f4










fd2c3ef761fb
1da177e4c3f4
1da177e4c3f4




80c802f3073e


157bfc25020f



80c802f3073e

1da177e4c3f4

92d63decc0b6

1da177e4c3f4

def8b4faff5c
aabc9761b69f

80c802f3073e
aabc9761b69f


157bfc25020f





aabc9761b69f
def8b4faff5c
aabc9761b69f
d511337a1eda
aabc9761b69f
fd2c3ef761fb
1da177e4c3f4

dbe5b4aaafc7
1da177e4c3f4

990078afbf90








1da177e4c3f4







d511337a1eda
1da177e4c3f4







d511337a1eda
1da177e4c3f4










6cc329610f2a
a1e59abf8249




15e318bdc6df
a1e59abf8249




21eddb5c1e97
1da177e4c3f4





21eddb5c1e97
1da177e4c3f4

ff88b30c717f
1da177e4c3f4


21eddb5c1e97
1da177e4c3f4










d511337a1eda

1da177e4c3f4
d5422efe680f


1da177e4c3f4
f6e1e25d703c
d5422efe680f

1da177e4c3f4
d5422efe680f
4e81bb8336a0
f6e1e25d703c
adf30907d638
d5422efe680f





1da177e4c3f4











d5422efe680f











d511337a1eda

d5422efe680f













d511337a1eda
1da177e4c3f4


99a66657b2f6


adf30907d638
1da177e4c3f4












d188ba86dd07
1da177e4c3f4
d188ba86dd07
1da177e4c3f4
d188ba86dd07



1da177e4c3f4


d511337a1eda
1da177e4c3f4


d188ba86dd07




1da177e4c3f4

d188ba86dd07


1da177e4c3f4



d511337a1eda
e4c1721642bb
1da177e4c3f4


d188ba86dd07
1da177e4c3f4













d5422efe680f















e4c1721642bb


1da177e4c3f4


e8a4e37716db
1da177e4c3f4


7e1dc7b6f709
1da177e4c3f4
7e1dc7b6f709
1da177e4c3f4




e8a4e37716db
1da177e4c3f4


7e1dc7b6f709
1da177e4c3f4
7e1dc7b6f709
1da177e4c3f4



9bb182a70075
e8a4e37716db
9bb182a70075




7e1dc7b6f709

9bb182a70075

15e318bdc6df

9bb182a70075



1da177e4c3f4
f8848067caff

1da177e4c3f4







f8848067caff

1da177e4c3f4
ff88b30c717f

1da177e4c3f4






f8848067caff

1da177e4c3f4










e53820de0f81
f8848067caff
e53820de0f81




7e1dc7b6f709

e53820de0f81

7e1dc7b6f709

e53820de0f81



f8848067caff
1da177e4c3f4



5794708f1155

dc00a5256036



5794708f1155

1da177e4c3f4


1a6509d99122
165ecc6373c7
1a6509d99122


1da177e4c3f4





165ecc6373c7
1da177e4c3f4









04ff12609445
1da177e4c3f4
7e50f84c94b8
1da177e4c3f4
1a6509d99122
1da177e4c3f4






3328715e6c1f











7e14ea1521d9
1da177e4c3f4
7e14ea1521d9


d2acc3479cbc
7e14ea1521d9
d2acc3479cbc
1da177e4c3f4

1da177e4c3f4

aba826958830
a63374631e71
d2acc3479cbc
b33eab08445d
aba826958830


1da177e4c3f4
d2acc3479cbc

d5fdd6babcfc
6f0bcf152582
d2acc3479cbc
1da177e4c3f4

d511337a1eda




2f32b51b609f
c35b7e72cd48
d511337a1eda



7e14ea1521d9

c35b7e72cd48









1da177e4c3f4
558f82ef6e0d
d511337a1eda

558f82ef6e0d

d511337a1eda
b27aeadb5948
d511337a1eda
b27aeadb5948





d3623099d350
870a2df4ca02
d511337a1eda

283bc9f35bbb
d511337a1eda











c454997e68eb

d511337a1eda











41a49cc3c02a
d511337a1eda
283bc9f35bbb
d511337a1eda

41a49cc3c02a

283bc9f35bbb
41a49cc3c02a









af11e31609d9






5a6d34162f5c










d511337a1eda

2e71029e2c32
d511337a1eda










7026b1ddb6b8
d511337a1eda







c4541b41c0e4


70be6c91c865
3328715e6c1f


c4541b41c0e4

d511337a1eda

ede2059dbaf9
7026b1ddb6b8
3328715e6c1f


d511337a1eda

d511337a1eda


63c43787d35e

d511337a1eda
63c43787d35e
d511337a1eda


7b77d161ce7e
7e14ea1521d9


d511337a1eda
7b77d161ce7e
d511337a1eda



ede2059dbaf9
7026b1ddb6b8
d511337a1eda

1da177e4c3f4

d511337a1eda


1da177e4c3f4





067b207b281d
1da177e4c3f4




1da177e4c3f4

0331b1f383e1
4c563f7669c1
d511337a1eda



283bc9f35bbb
1da177e4c3f4
8ca2e93b557f

4e81bb8336a0
ef41aaa0b755

d511337a1eda

2e71029e2c32
880a6fab8f6b
1da177e4c3f4
776e9dd90ca2
d511337a1eda
e473fcb47257
bd55775c8dd6
a70486f0e669

bd55775c8dd6
d511337a1eda
1da177e4c3f4
80c9abaabf42
d511337a1eda


283bc9f35bbb
d511337a1eda



8d549c4f5d92
80c9abaabf42

d511337a1eda




















1da177e4c3f4
70e94e66aec2









1da177e4c3f4



70e94e66aec2
1da177e4c3f4
70e94e66aec2
1da177e4c3f4


77d8d7a6848c




a6483b790f8e

f8cd54884e67
be33690d8fcf



a6483b790f8e
be33690d8fcf



f8cd54884e67
0f24558e9156













a6483b790f8e
f8cd54884e67
ee5c23176fcc




851586218f5d
0f99be0d115a



851586218f5d
4447bb33f094



9736acf395d3




80c9abaabf42
af2f464e326e





















ee5c23176fcc





80c9abaabf42

0f99be0d115a
80c9abaabf42

4447bb33f094




80c9abaabf42













f8cd54884e67
def8b4faff5c
005011211f55



def8b4faff5c
005011211f55
bf825f81b454


4efd7e833591
bf825f81b454





e3dfa389fd2c
bf825f81b454
1d1e34ddd48d
bf825f81b454
1d1e34ddd48d


bf825f81b454

70be6c91c865



















1da177e4c3f4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818


                   
                           



                           
                         
                          
                        
                      
                        
                        
                       


                     
                   


                        
                     


                            


                             
 







                                               
                                                  
                                                  

                                                                             

                                                                             
 
                             
                                                                                         
     
                                                     

      





























































                                                                                


                                      

                                      
                                    
                                           

  
                                               
                   
                                       
               
                                               

                                              

                                      





                                       
                                     
                                       
 

                                      

                                   











                                                    
                                            




                                     
                                      

                                      
                                      
                                       



                                       


                                      







                                                                           
                                                 
 

                                                                              
                                                  
 
                                                 
                                       
 




                                                                        






                                                    



                                        
                                       
 


                                                             
                            
                                         
 

                                                                
                                      
                                            
                                                
                                            
 


                                          




                                                              




                                                      

                                        
                          
 








                           
                                                            
                 



                          
                           
                         

               
                    
                       
                      
                        

  




                                                                 


                                                



                                                                       
                  



                                       
                                         
                                                                    

                                                                

                                                                            


                                                                      
                                                                      

                                                                   
                                                                   


                                                                   
                                                                  
                                                                   
                                                                    
                                                                                             

  




                                                                     

                 



                                                                  
 
                          
                                       
                                      
                                          
                                       
                                                       
                                                         
                                                                    

                                                                          



                                                                             

                                                                                                       
                                                                                                 
                                                                                       

                                                                      

                                                                       

                                                                        
                                                                             

  



                                                                     
 









                                                                             
                                                    
 
                  

                                             

                                      
                                 
                                 

                                 
 
                                                                    
                                                                   
                                                                                   
                                                                                     

                                                                                
                                                                                            
                                                                          
                                                                          

  

                                                                              
 
                  




















                                                                             
                                                                











                                                                          











                                                                            
 
                                         

                             





                                  

  

                                                             
 




















                                                                                     
                  










                                                                 

                                             
                                      
 
                                  
                                     

                                                                  
                                      

                                                    
                                         
 
                                       
                                        
 
                                               


                                       

  
                                 
 










                                           





                                           
                    
                                       

                                      





                                                               
                                     
                                      

                                         
                                     


                                         
                                           
                                      


                                       
                                        
                                       
                                          
                                                         
                                    

  
                                                              



                                      






                                         












                                           
                                         









                                              
 
                 

                                     
                                                                                          
                                                                                                             
                                                                                                          
                                                                                                           
                                                                                                           
                                                                                                                      




                                                                           
                                                                      

  

                                            
 













                                                                                  





                                                                  
                                         

                                                    
               







                                   
              



                                                                    




                                                                              
                                         




                                                                              


                                                                        








                                              


                                                    





                                                                              




                                                                       
                                         
 
                              
                            



                                                                            
                          
                                                                   

                                              
 

                               
                                                                       
                                                           

                              


                                                 
 
                                                             

                                                                            






                                                                            
                                          

 




                                                                                








                                                                               
     

                                                                            
                                                         



                                                                               
                                                            



                                                                         
                                                        



                                                                            
                                                           







                                                                         




                                                                               













                                                                             
                                
 





                                                            
                                                     



                                                           
                                            

 





                                                                      
 
                                               
 




                                                         










                                                        

                                                                     
 

                                  


                
                                                                  



                                                                               
                                     

                  
                            



                                                         
                                     

         
                    

 







                                                                     
                 
                                                                           
 
                    
                                 

                         
                             
                          
                                        


                            
                                              
                      
                        
                                            
                      
                         
                                                        
                      






                                       
                                                                           
 
                    
                                 

                         
                             
                          
                                        


                            
                                              
                      
                         
                                                           
                      





                                       

                                                                        
 



                                                                             
                                                                                       







                                                
                                                                                       
 
                    


      










                                                                            
                 
               




                                            


                                                       



                                      

                         

                             

                         

  
                  

                                                          
                                                  


                                                 





                             
 
      
 
                                                                    
 
                 

                                       
                                                      

  








                                                     







                                        
                                            







                                                   
                                                   










                                  
                                                                




                                     
                                                 




                 
                                                                                





                                                      
                                                                                

                                                                  
                                                                                                       


                 
                                                                                                    










                                                       

                                                                    
 


                                                                        
 
                                            

                                                              
                                                
                                                                  
 
                                                             
                                                       





                                                                                                         











                                                                                   











                                                                      

                                                                













                                                                            
                                                                     


                                                                                


                                                           
                                                     












                                                          
                                                                    
 
                                                                               
 



                                                             


                 
                                                         


                                                       




                                                             

                                        


                                                             



                                        
                                           
 


                                                          
                                                                                             













                                                                                                         















                                                                      


                                                        


                 
                                                                               


                        
                                                          
                      
                                                          




                    
                                                                               


                        
                                                          
                      
                                                          



                    
                 
                                                




                                                                      

                                                                        

                      

                                             



                      
                     

                                                                                  







                                                                                 

                                                                                  
 

                                                                                             






                                                                

                                                                               










                                                                 
                     
                                                                              




                                                  

                                                                                          

                                                  

                                                                                          



                 
                                                             



                                             

                                                             



                                                                           

 


                             
                            
                    


                          





                            
                    









                            
                     
                       
                             
               
                                                






                                                











                                                                          
                       
                                            


                                                                           
 
                                          
                     

  

                            
                                            
                                                          
 
                                       


                     
                     

                                                                           
                                                                      
                                        
                     

  




                                      
                               
                  



                            

                               









                                   
 
                             

                                     

      
                                      
                    
                                       





                                                    
                                                                 
                                                              

                                                                          
                                                                         











                                                                     

                                                                       











                                                                             
                             
                                                                         
                                                           

                                                                            

                                                                                
                                                                               









                                                                                   






                                                 










                      

                                                                           
                                                                 










                                                                             
                                                      







                                                                         


                                                                             
                                                   


                                                                       

 

                                                                    
                                                                        
                                                              


                                                                                      

                                                                                


                                                                   

                                                               
                                                           
                                                          


                                                                
                                                     


                                                                                      
                                                                               
                                                                                 



                                                                             
                                                                        
                                                              

                                                                    

                  


                                                              





                                                                                               
                                                                           




                               

      
                                                                  
 



                                                                        
                                                                           
                                                                      

                                                                    
                                                                    

                                                                               

                                                                            
                                                                 
                                               
                          
                                                
                                                                 
                                                                               
                                                              

                                                                         
                                                        
                                                                             
 
                          


                                                                
                                                                                    



                                                                  
                                                            

      




















                                                                               
 









                                                            



                         
                                                                      
                      
                                              


         




                                               

                                                    
 



                          
                                               



                                                                     
 













                                                                     
      
 




                                                           
                                                           



                                                           
                                                                     



                                                           




                                                                                     
                          





















                                                                            





                                                                                      

                                                                       
                                                             

 




                                                                                      













                                                                        
 
                  



                                                                      
      
 


                                                                           
                                                                                 





                                
                                                                               
 
                    
 


                                                                            

 



















                                                                              
                         
#ifndef _NET_XFRM_H
#define _NET_XFRM_H

#include <linux/compiler.h>
#include <linux/xfrm.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
#include <linux/in6.h>
#include <linux/mutex.h>
#include <linux/audit.h>
#include <linux/slab.h>

#include <net/sock.h>
#include <net/dst.h>
#include <net/ip.h>
#include <net/route.h>
#include <net/ipv6.h>
#include <net/ip6_fib.h>
#include <net/flow.h>

#include <linux/interrupt.h>

#ifdef CONFIG_XFRM_STATISTICS
#include <net/snmp.h>
#endif

#define XFRM_PROTO_ESP		50
#define XFRM_PROTO_AH		51
#define XFRM_PROTO_COMP		108
#define XFRM_PROTO_IPIP		4
#define XFRM_PROTO_IPV6		41
#define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
#define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS

#define XFRM_ALIGN4(len)	(((len) + 3) & ~3)
#define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
#define MODULE_ALIAS_XFRM_MODE(family, encap) \
	MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))

#ifdef CONFIG_XFRM_STATISTICS
#define XFRM_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
#else
#define XFRM_INC_STATS(net, field)	((void)(net))
#endif


/* Organization of SPD aka "XFRM rules"
   ------------------------------------

   Basic objects:
   - policy rule, struct xfrm_policy (=SPD entry)
   - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)
   - instance of a transformer, struct xfrm_state (=SA)
   - template to clone xfrm_state, struct xfrm_tmpl

   SPD is plain linear list of xfrm_policy rules, ordered by priority.
   (To be compatible with existing pfkeyv2 implementations,
   many rules with priority of 0x7fffffff are allowed to exist and
   such rules are ordered in an unpredictable way, thanks to bsd folks.)

   Lookup is plain linear search until the first match with selector.

   If "action" is "block", then we prohibit the flow, otherwise:
   if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,
   policy entry has list of up to XFRM_MAX_DEPTH transformations,
   described by templates xfrm_tmpl. Each template is resolved
   to a complete xfrm_state (see below) and we pack bundle of transformations
   to a dst_entry returned to requestor.

   dst -. xfrm  .-> xfrm_state #1
    |---. child .-> dst -. xfrm .-> xfrm_state #2
                     |---. child .-> dst -. xfrm .-> xfrm_state #3
                                      |---. child .-> NULL

   Bundles are cached at xrfm_policy struct (field ->bundles).


   Resolution of xrfm_tmpl
   -----------------------
   Template contains:
   1. ->mode		Mode: transport or tunnel
   2. ->id.proto	Protocol: AH/ESP/IPCOMP
   3. ->id.daddr	Remote tunnel endpoint, ignored for transport mode.
      Q: allow to resolve security gateway?
   4. ->id.spi          If not zero, static SPI.
   5. ->saddr		Local tunnel endpoint, ignored for transport mode.
   6. ->algos		List of allowed algos. Plain bitmask now.
      Q: ealgos, aalgos, calgos. What a mess...
   7. ->share		Sharing mode.
      Q: how to implement private sharing mode? To add struct sock* to
      flow id?

   Having this template we search through SAD searching for entries
   with appropriate mode/proto/algo, permitted by selector.
   If no appropriate entry found, it is requested from key manager.

   PROBLEMS:
   Q: How to find all the bundles referring to a physical path for
      PMTU discovery? Seems, dst should contain list of all parents...
      and enter to infinite locking hierarchy disaster.
      No! It is easier, we will not search for them, let them find us.
      We add genid to each dst plus pointer to genid of raw IP route,
      pmtu disc will update pmtu on raw IP route and increase its genid.
      dst_check() will see this for top level and trigger resyncing
      metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
 */

struct xfrm_state_walk {
	struct list_head	all;
	u8			state;
	u8			dying;
	u8			proto;
	u32			seq;
	struct xfrm_address_filter *filter;
};

/* Full description of state of transformer. */
struct xfrm_state {
	possible_net_t		xs_net;
	union {
		struct hlist_node	gclist;
		struct hlist_node	bydst;
	};
	struct hlist_node	bysrc;
	struct hlist_node	byspi;

	atomic_t		refcnt;
	spinlock_t		lock;

	struct xfrm_id		id;
	struct xfrm_selector	sel;
	struct xfrm_mark	mark;
	u32			tfcpad;

	u32			genid;

	/* Key manager bits */
	struct xfrm_state_walk	km;

	/* Parameters of this state. */
	struct {
		u32		reqid;
		u8		mode;
		u8		replay_window;
		u8		aalgo, ealgo, calgo;
		u8		flags;
		u16		family;
		xfrm_address_t	saddr;
		int		header_len;
		int		trailer_len;
		u32		extra_flags;
	} props;

	struct xfrm_lifetime_cfg lft;

	/* Data for transformer */
	struct xfrm_algo_auth	*aalg;
	struct xfrm_algo	*ealg;
	struct xfrm_algo	*calg;
	struct xfrm_algo_aead	*aead;
	const char		*geniv;

	/* Data for encapsulator */
	struct xfrm_encap_tmpl	*encap;

	/* Data for care-of address */
	xfrm_address_t	*coaddr;

	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
	struct xfrm_state	*tunnel;

	/* If a tunnel, number of users + 1 */
	atomic_t		tunnel_users;

	/* State for replay detection */
	struct xfrm_replay_state replay;
	struct xfrm_replay_state_esn *replay_esn;

	/* Replay detection state at the time we sent the last notification */
	struct xfrm_replay_state preplay;
	struct xfrm_replay_state_esn *preplay_esn;

	/* The functions for replay detection. */
	const struct xfrm_replay *repl;

	/* internal flag that only holds state for delayed aevent at the
	 * moment
	*/
	u32			xflags;

	/* Replay detection notification settings */
	u32			replay_maxage;
	u32			replay_maxdiff;

	/* Replay detection notification timer */
	struct timer_list	rtimer;

	/* Statistics */
	struct xfrm_stats	stats;

	struct xfrm_lifetime_cur curlft;
	struct tasklet_hrtimer	mtimer;

	/* used to fix curlft->add_time when changing date */
	long		saved_tmo;

	/* Last used time */
	unsigned long		lastused;

	/* Reference to data common to all the instances of this
	 * transformer. */
	const struct xfrm_type	*type;
	struct xfrm_mode	*inner_mode;
	struct xfrm_mode	*inner_mode_iaf;
	struct xfrm_mode	*outer_mode;

	/* Security context */
	struct xfrm_sec_ctx	*security;

	/* Private data of this transformer, format is opaque,
	 * interpreted by xfrm_type methods. */
	void			*data;
};

static inline struct net *xs_net(struct xfrm_state *x)
{
	return read_pnet(&x->xs_net);
}

/* xflags - make enum if more show up */
#define XFRM_TIME_DEFER	1
#define XFRM_SOFT_EXPIRE 2

enum {
	XFRM_STATE_VOID,
	XFRM_STATE_ACQ,
	XFRM_STATE_VALID,
	XFRM_STATE_ERROR,
	XFRM_STATE_EXPIRED,
	XFRM_STATE_DEAD
};

/* callback structure passed from either netlink or pfkey */
struct km_event {
	union {
		u32 hard;
		u32 proto;
		u32 byid;
		u32 aevent;
		u32 type;
	} data;

	u32	seq;
	u32	portid;
	u32	event;
	struct net *net;
};

struct xfrm_replay {
	void	(*advance)(struct xfrm_state *x, __be32 net_seq);
	int	(*check)(struct xfrm_state *x,
			 struct sk_buff *skb,
			 __be32 net_seq);
	int	(*recheck)(struct xfrm_state *x,
			   struct sk_buff *skb,
			   __be32 net_seq);
	void	(*notify)(struct xfrm_state *x, int event);
	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);
};

struct net_device;
struct xfrm_type;
struct xfrm_dst;
struct xfrm_policy_afinfo {
	unsigned short		family;
	struct dst_ops		*dst_ops;
	void			(*garbage_collect)(struct net *net);
	struct dst_entry	*(*dst_lookup)(struct net *net,
					       int tos, int oif,
					       const xfrm_address_t *saddr,
					       const xfrm_address_t *daddr);
	int			(*get_saddr)(struct net *net, int oif,
					     xfrm_address_t *saddr,
					     xfrm_address_t *daddr);
	void			(*decode_session)(struct sk_buff *skb,
						  struct flowi *fl,
						  int reverse);
	int			(*get_tos)(const struct flowi *fl);
	int			(*init_path)(struct xfrm_dst *path,
					     struct dst_entry *dst,
					     int nfheader_len);
	int			(*fill_dst)(struct xfrm_dst *xdst,
					    struct net_device *dev,
					    const struct flowi *fl);
	struct dst_entry	*(*blackhole_route)(struct net *net, struct dst_entry *orig);
};

int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
void km_policy_notify(struct xfrm_policy *xp, int dir,
		      const struct km_event *c);
void km_state_notify(struct xfrm_state *x, const struct km_event *c);

struct xfrm_tmpl;
int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
	     struct xfrm_policy *pol);
void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
int __xfrm_state_delete(struct xfrm_state *x);

struct xfrm_state_afinfo {
	unsigned int		family;
	unsigned int		proto;
	__be16			eth_proto;
	struct module		*owner;
	const struct xfrm_type	*type_map[IPPROTO_MAX];
	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
	int			(*init_flags)(struct xfrm_state *x);
	void			(*init_tempsel)(struct xfrm_selector *sel,
						const struct flowi *fl);
	void			(*init_temprop)(struct xfrm_state *x,
						const struct xfrm_tmpl *tmpl,
						const xfrm_address_t *daddr,
						const xfrm_address_t *saddr);
	int			(*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
	int			(*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
	int			(*output_finish)(struct sock *sk, struct sk_buff *skb);
	int			(*extract_input)(struct xfrm_state *x,
						 struct sk_buff *skb);
	int			(*extract_output)(struct xfrm_state *x,
						  struct sk_buff *skb);
	int			(*transport_finish)(struct sk_buff *skb,
						    int async);
	void			(*local_error)(struct sk_buff *skb, u32 mtu);
};

int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);

struct xfrm_input_afinfo {
	unsigned int		family;
	struct module		*owner;
	int			(*callback)(struct sk_buff *skb, u8 protocol,
					    int err);
};

int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo);
int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo);

void xfrm_state_delete_tunnel(struct xfrm_state *x);

struct xfrm_type {
	char			*description;
	struct module		*owner;
	u8			proto;
	u8			flags;
#define XFRM_TYPE_NON_FRAGMENT	1
#define XFRM_TYPE_REPLAY_PROT	2
#define XFRM_TYPE_LOCAL_COADDR	4
#define XFRM_TYPE_REMOTE_COADDR	8

	int			(*init_state)(struct xfrm_state *x);
	void			(*destructor)(struct xfrm_state *);
	int			(*input)(struct xfrm_state *, struct sk_buff *skb);
	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
	int			(*reject)(struct xfrm_state *, struct sk_buff *,
					  const struct flowi *);
	int			(*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
	/* Estimate maximal size of result of transformation of a dgram */
	u32			(*get_mtu)(struct xfrm_state *, int size);
};

int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);

struct xfrm_mode {
	/*
	 * Remove encapsulation header.
	 *
	 * The IP header will be moved over the top of the encapsulation
	 * header.
	 *
	 * On entry, the transport header shall point to where the IP header
	 * should be and the network header shall be set to where the IP
	 * header currently is.  skb->data shall point to the start of the
	 * payload.
	 */
	int (*input2)(struct xfrm_state *x, struct sk_buff *skb);

	/*
	 * This is the actual input entry point.
	 *
	 * For transport mode and equivalent this would be identical to
	 * input2 (which does not need to be set).  While tunnel mode
	 * and equivalent would set this to the tunnel encapsulation function
	 * xfrm4_prepare_input that would in turn call input2.
	 */
	int (*input)(struct xfrm_state *x, struct sk_buff *skb);

	/*
	 * Add encapsulation header.
	 *
	 * On exit, the transport header will be set to the start of the
	 * encapsulation header to be filled in by x->type->output and
	 * the mac header will be set to the nextheader (protocol for
	 * IPv4) field of the extension header directly preceding the
	 * encapsulation header, or in its absence, that of the top IP
	 * header.  The value of the network header will always point
	 * to the top IP header while skb->data will point to the payload.
	 */
	int (*output2)(struct xfrm_state *x,struct sk_buff *skb);

	/*
	 * This is the actual output entry point.
	 *
	 * For transport mode and equivalent this would be identical to
	 * output2 (which does not need to be set).  While tunnel mode
	 * and equivalent would set this to a tunnel encapsulation function
	 * (xfrm4_prepare_output or xfrm6_prepare_output) that would in turn
	 * call output2.
	 */
	int (*output)(struct xfrm_state *x, struct sk_buff *skb);

	struct xfrm_state_afinfo *afinfo;
	struct module *owner;
	unsigned int encap;
	int flags;
};

/* Flags for xfrm_mode. */
enum {
	XFRM_MODE_FLAG_TUNNEL = 1,
};

int xfrm_register_mode(struct xfrm_mode *mode, int family);
int xfrm_unregister_mode(struct xfrm_mode *mode, int family);

static inline int xfrm_af2proto(unsigned int family)
{
	switch(family) {
	case AF_INET:
		return IPPROTO_IPIP;
	case AF_INET6:
		return IPPROTO_IPV6;
	default:
		return 0;
	}
}

static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
{
	if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
	    (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
		return x->inner_mode;
	else
		return x->inner_mode_iaf;
}

struct xfrm_tmpl {
/* id in template is interpreted as:
 * daddr - destination of tunnel, may be zero for transport mode.
 * spi   - zero to acquire spi. Not zero if spi is static, then
 *	   daddr must be fixed too.
 * proto - AH/ESP/IPCOMP
 */
	struct xfrm_id		id;

/* Source address of tunnel. Ignored, if it is not a tunnel. */
	xfrm_address_t		saddr;

	unsigned short		encap_family;

	u32			reqid;

/* Mode: transport, tunnel etc. */
	u8			mode;

/* Sharing mode: unique, this session only, this user only etc. */
	u8			share;

/* May skip this transfomration if no SA is found */
	u8			optional;

/* Skip aalgos/ealgos/calgos checks. */
	u8			allalgs;

/* Bit mask of algos allowed for acquisition */
	u32			aalgos;
	u32			ealgos;
	u32			calgos;
};

#define XFRM_MAX_DEPTH		6

struct xfrm_policy_walk_entry {
	struct list_head	all;
	u8			dead;
};

struct xfrm_policy_walk {
	struct xfrm_policy_walk_entry walk;
	u8 type;
	u32 seq;
};

struct xfrm_policy_queue {
	struct sk_buff_head	hold_queue;
	struct timer_list	hold_timer;
	unsigned long		timeout;
};

struct xfrm_policy {
	possible_net_t		xp_net;
	struct hlist_node	bydst;
	struct hlist_node	byidx;

	/* This lock only affects elements except for entry. */
	rwlock_t		lock;
	atomic_t		refcnt;
	struct timer_list	timer;

	struct flow_cache_object flo;
	atomic_t		genid;
	u32			priority;
	u32			index;
	struct xfrm_mark	mark;
	struct xfrm_selector	selector;
	struct xfrm_lifetime_cfg lft;
	struct xfrm_lifetime_cur curlft;
	struct xfrm_policy_walk_entry walk;
	struct xfrm_policy_queue polq;
	u8			type;
	u8			action;
	u8			flags;
	u8			xfrm_nr;
	u16			family;
	struct xfrm_sec_ctx	*security;
	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
	struct rcu_head		rcu;
};

static inline struct net *xp_net(const struct xfrm_policy *xp)
{
	return read_pnet(&xp->xp_net);
}

struct xfrm_kmaddress {
	xfrm_address_t          local;
	xfrm_address_t          remote;
	u32			reserved;
	u16			family;
};

struct xfrm_migrate {
	xfrm_address_t		old_daddr;
	xfrm_address_t		old_saddr;
	xfrm_address_t		new_daddr;
	xfrm_address_t		new_saddr;
	u8			proto;
	u8			mode;
	u16			reserved;
	u32			reqid;
	u16			old_family;
	u16			new_family;
};

#define XFRM_KM_TIMEOUT                30
/* what happened */
#define XFRM_REPLAY_UPDATE	XFRM_AE_CR
#define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE

/* default aevent timeout in units of 100ms */
#define XFRM_AE_ETIME			10
/* Async Event timer multiplier */
#define XFRM_AE_ETH_M			10
/* default seq threshold size */
#define XFRM_AE_SEQT_SIZE		2

struct xfrm_mgr {
	struct list_head	list;
	char			*id;
	int			(*notify)(struct xfrm_state *x, const struct km_event *c);
	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
	int			(*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
	int			(*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
	int			(*migrate)(const struct xfrm_selector *sel,
					   u8 dir, u8 type,
					   const struct xfrm_migrate *m,
					   int num_bundles,
					   const struct xfrm_kmaddress *k);
	bool			(*is_alive)(const struct km_event *c);
};

int xfrm_register_km(struct xfrm_mgr *km);
int xfrm_unregister_km(struct xfrm_mgr *km);

struct xfrm_tunnel_skb_cb {
	union {
		struct inet_skb_parm h4;
		struct inet6_skb_parm h6;
	} header;

	union {
		struct ip_tunnel *ip4;
		struct ip6_tnl *ip6;
	} tunnel;
};

#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))

/*
 * This structure is used for the duration where packets are being
 * transformed by IPsec.  As soon as the packet leaves IPsec the
 * area beyond the generic IP part may be overwritten.
 */
struct xfrm_skb_cb {
	struct xfrm_tunnel_skb_cb header;

        /* Sequence number for replay protection. */
	union {
		struct {
			__u32 low;
			__u32 hi;
		} output;
		struct {
			__be32 low;
			__be32 hi;
		} input;
	} seq;
};

#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))

/*
 * This structure is used by the afinfo prepare_input/prepare_output functions
 * to transmit header information to the mode input/output functions.
 */
struct xfrm_mode_skb_cb {
	struct xfrm_tunnel_skb_cb header;

	/* Copied from header for IPv4, always set to zero and DF for IPv6. */
	__be16 id;
	__be16 frag_off;

	/* IP header length (excluding options or extension headers). */
	u8 ihl;

	/* TOS for IPv4, class for IPv6. */
	u8 tos;

	/* TTL for IPv4, hop limitfor IPv6. */
	u8 ttl;

	/* Protocol for IPv4, NH for IPv6. */
	u8 protocol;

	/* Option length for IPv4, zero for IPv6. */
	u8 optlen;

	/* Used by IPv6 only, zero for IPv4. */
	u8 flow_lbl[3];
};

#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))

/*
 * This structure is used by the input processing to locate the SPI and
 * related information.
 */
struct xfrm_spi_skb_cb {
	struct xfrm_tunnel_skb_cb header;

	unsigned int daddroff;
	unsigned int family;
};

#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))

#ifdef CONFIG_AUDITSYSCALL
static inline struct audit_buffer *xfrm_audit_start(const char *op)
{
	struct audit_buffer *audit_buf = NULL;

	if (audit_enabled == 0)
		return NULL;
	audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
				    AUDIT_MAC_IPSEC_EVENT);
	if (audit_buf == NULL)
		return NULL;
	audit_log_format(audit_buf, "op=%s", op);
	return audit_buf;
}

static inline void xfrm_audit_helper_usrinfo(bool task_valid,
					     struct audit_buffer *audit_buf)
{
	const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
					    audit_get_loginuid(current) :
					    INVALID_UID);
	const unsigned int ses = task_valid ? audit_get_sessionid(current) :
		(unsigned int) -1;

	audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
	audit_log_task_context(audit_buf);
}

void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
			      bool task_valid);
void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
				      struct sk_buff *skb);
void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
			     __be32 net_seq);
void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
			       __be32 net_seq);
void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
			      u8 proto);
#else

static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
					 bool task_valid)
{
}

static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
					    bool task_valid)
{
}

static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
					bool task_valid)
{
}

static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
					   bool task_valid)
{
}

static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
					     struct sk_buff *skb)
{
}

static inline void xfrm_audit_state_replay(struct xfrm_state *x,
					   struct sk_buff *skb, __be32 net_seq)
{
}

static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
				      u16 family)
{
}

static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
				      __be32 net_spi, __be32 net_seq)
{
}

static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
				     struct sk_buff *skb, u8 proto)
{
}
#endif /* CONFIG_AUDITSYSCALL */

static inline void xfrm_pol_hold(struct xfrm_policy *policy)
{
	if (likely(policy != NULL))
		atomic_inc(&policy->refcnt);
}

void xfrm_policy_destroy(struct xfrm_policy *policy);

static inline void xfrm_pol_put(struct xfrm_policy *policy)
{
	if (atomic_dec_and_test(&policy->refcnt))
		xfrm_policy_destroy(policy);
}

static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
{
	int i;
	for (i = npols - 1; i >= 0; --i)
		xfrm_pol_put(pols[i]);
}

void __xfrm_state_destroy(struct xfrm_state *);

static inline void __xfrm_state_put(struct xfrm_state *x)
{
	atomic_dec(&x->refcnt);
}

static inline void xfrm_state_put(struct xfrm_state *x)
{
	if (atomic_dec_and_test(&x->refcnt))
		__xfrm_state_destroy(x);
}

static inline void xfrm_state_hold(struct xfrm_state *x)
{
	atomic_inc(&x->refcnt);
}

static inline bool addr_match(const void *token1, const void *token2,
			      int prefixlen)
{
	const __be32 *a1 = token1;
	const __be32 *a2 = token2;
	int pdw;
	int pbi;

	pdw = prefixlen >> 5;	  /* num of whole u32 in prefix */
	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */

	if (pdw)
		if (memcmp(a1, a2, pdw << 2))
			return false;

	if (pbi) {
		__be32 mask;

		mask = htonl((0xffffffff) << (32 - pbi));

		if ((a1[pdw] ^ a2[pdw]) & mask)
			return false;
	}

	return true;
}

static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
{
	/* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
	if (prefixlen == 0)
		return true;
	return !((a1 ^ a2) & htonl(0xFFFFFFFFu << (32 - prefixlen)));
}

static __inline__
__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
{
	__be16 port;
	switch(fl->flowi_proto) {
	case IPPROTO_TCP:
	case IPPROTO_UDP:
	case IPPROTO_UDPLITE:
	case IPPROTO_SCTP:
		port = uli->ports.sport;
		break;
	case IPPROTO_ICMP:
	case IPPROTO_ICMPV6:
		port = htons(uli->icmpt.type);
		break;
	case IPPROTO_MH:
		port = htons(uli->mht.type);
		break;
	case IPPROTO_GRE:
		port = htons(ntohl(uli->gre_key) >> 16);
		break;
	default:
		port = 0;	/*XXX*/
	}
	return port;
}

static __inline__
__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
{
	__be16 port;
	switch(fl->flowi_proto) {
	case IPPROTO_TCP:
	case IPPROTO_UDP:
	case IPPROTO_UDPLITE:
	case IPPROTO_SCTP:
		port = uli->ports.dport;
		break;
	case IPPROTO_ICMP:
	case IPPROTO_ICMPV6:
		port = htons(uli->icmpt.code);
		break;
	case IPPROTO_GRE:
		port = htons(ntohl(uli->gre_key) & 0xffff);
		break;
	default:
		port = 0;	/*XXX*/
	}
	return port;
}

bool xfrm_selector_match(const struct xfrm_selector *sel,
			 const struct flowi *fl, unsigned short family);

#ifdef CONFIG_SECURITY_NETWORK_XFRM
/*	If neither has a context --> match
 * 	Otherwise, both must have a context and the sids, doi, alg must match
 */
static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
{
	return ((!s1 && !s2) ||
		(s1 && s2 &&
		 (s1->ctx_sid == s2->ctx_sid) &&
		 (s1->ctx_doi == s2->ctx_doi) &&
		 (s1->ctx_alg == s2->ctx_alg)));
}
#else
static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
{
	return true;
}
#endif

/* A struct encoding bundle of transformations to apply to some set of flow.
 *
 * dst->child points to the next element of bundle.
 * dst->xfrm  points to an instanse of transformer.
 *
 * Due to unfortunate limitations of current routing cache, which we
 * have no time to fix, it mirrors struct rtable and bound to the same
 * routing key, including saddr,daddr. However, we can have many of
 * bundles differing by session id. All the bundles grow from a parent
 * policy rule.
 */
struct xfrm_dst {
	union {
		struct dst_entry	dst;
		struct rtable		rt;
		struct rt6_info		rt6;
	} u;
	struct dst_entry *route;
	struct flow_cache_object flo;
	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
	int num_pols, num_xfrms;
#ifdef CONFIG_XFRM_SUB_POLICY
	struct flowi *origin;
	struct xfrm_selector *partner;
#endif
	u32 xfrm_genid;
	u32 policy_genid;
	u32 route_mtu_cached;
	u32 child_mtu_cached;
	u32 route_cookie;
	u32 path_cookie;
};

#ifdef CONFIG_XFRM
static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
{
	xfrm_pols_put(xdst->pols, xdst->num_pols);
	dst_release(xdst->route);
	if (likely(xdst->u.dst.xfrm))
		xfrm_state_put(xdst->u.dst.xfrm);
#ifdef CONFIG_XFRM_SUB_POLICY
	kfree(xdst->origin);
	xdst->origin = NULL;
	kfree(xdst->partner);
	xdst->partner = NULL;
#endif
}
#endif

void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);

struct sec_path {
	atomic_t		refcnt;
	int			len;
	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
};

static inline int secpath_exists(struct sk_buff *skb)
{
#ifdef CONFIG_XFRM
	return skb->sp != NULL;
#else
	return 0;
#endif
}

static inline struct sec_path *
secpath_get(struct sec_path *sp)
{
	if (sp)
		atomic_inc(&sp->refcnt);
	return sp;
}

void __secpath_destroy(struct sec_path *sp);

static inline void
secpath_put(struct sec_path *sp)
{
	if (sp && atomic_dec_and_test(&sp->refcnt))
		__secpath_destroy(sp);
}

struct sec_path *secpath_dup(struct sec_path *src);

static inline void
secpath_reset(struct sk_buff *skb)
{
#ifdef CONFIG_XFRM
	secpath_put(skb->sp);
	skb->sp = NULL;
#endif
}

static inline int
xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
{
	switch (family) {
	case AF_INET:
		return addr->a4 == 0;
	case AF_INET6:
		return ipv6_addr_any(&addr->in6);
	}
	return 0;
}

static inline int
__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
{
	return	(tmpl->saddr.a4 &&
		 tmpl->saddr.a4 != x->props.saddr.a4);
}

static inline int
__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
{
	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
		 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
}

static inline int
xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
{
	switch (family) {
	case AF_INET:
		return __xfrm4_state_addr_cmp(tmpl, x);
	case AF_INET6:
		return __xfrm6_state_addr_cmp(tmpl, x);
	}
	return !0;
}

#ifdef CONFIG_XFRM
int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
			unsigned short family);

static inline int __xfrm_policy_check2(struct sock *sk, int dir,
				       struct sk_buff *skb,
				       unsigned int family, int reverse)
{
	struct net *net = dev_net(skb->dev);
	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);

	if (sk && sk->sk_policy[XFRM_POLICY_IN])
		return __xfrm_policy_check(sk, ndir, skb, family);

	return	(!net->xfrm.policy_count[dir] && !skb->sp) ||
		(skb_dst(skb)->flags & DST_NOPOLICY) ||
		__xfrm_policy_check(sk, ndir, skb, family);
}

static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
{
	return __xfrm_policy_check2(sk, dir, skb, family, 0);
}

static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
{
	return xfrm_policy_check(sk, dir, skb, AF_INET);
}

static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
{
	return xfrm_policy_check(sk, dir, skb, AF_INET6);
}

static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
					     struct sk_buff *skb)
{
	return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
}

static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
					     struct sk_buff *skb)
{
	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
}

int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
			  unsigned int family, int reverse);

static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
				      unsigned int family)
{
	return __xfrm_decode_session(skb, fl, family, 0);
}

static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
					      struct flowi *fl,
					      unsigned int family)
{
	return __xfrm_decode_session(skb, fl, family, 1);
}

int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);

static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
	struct net *net = dev_net(skb->dev);

	return	!net->xfrm.policy_count[XFRM_POLICY_OUT] ||
		(skb_dst(skb)->flags & DST_NOXFRM) ||
		__xfrm_route_forward(skb, family);
}

static inline int xfrm4_route_forward(struct sk_buff *skb)
{
	return xfrm_route_forward(skb, AF_INET);
}

static inline int xfrm6_route_forward(struct sk_buff *skb)
{
	return xfrm_route_forward(skb, AF_INET6);
}

int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);

static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
{
	sk->sk_policy[0] = NULL;
	sk->sk_policy[1] = NULL;
	if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
		return __xfrm_sk_clone_policy(sk, osk);
	return 0;
}

int xfrm_policy_delete(struct xfrm_policy *pol, int dir);

static inline void xfrm_sk_free_policy(struct sock *sk)
{
	struct xfrm_policy *pol;

	pol = rcu_dereference_protected(sk->sk_policy[0], 1);
	if (unlikely(pol != NULL)) {
		xfrm_policy_delete(pol, XFRM_POLICY_MAX);
		sk->sk_policy[0] = NULL;
	}
	pol = rcu_dereference_protected(sk->sk_policy[1], 1);
	if (unlikely(pol != NULL)) {
		xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
		sk->sk_policy[1] = NULL;
	}
}

void xfrm_garbage_collect(struct net *net);

#else

static inline void xfrm_sk_free_policy(struct sock *sk) {}
static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }  
static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } 
static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
{ 
	return 1; 
} 
static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
{
	return 1;
}
static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
{
	return 1;
}
static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
					      struct flowi *fl,
					      unsigned int family)
{
	return -ENOSYS;
}
static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
					     struct sk_buff *skb)
{
	return 1;
}
static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
					     struct sk_buff *skb)
{
	return 1;
}
static inline void xfrm_garbage_collect(struct net *net)
{
}
#endif

static __inline__
xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
{
	switch (family){
	case AF_INET:
		return (xfrm_address_t *)&fl->u.ip4.daddr;
	case AF_INET6:
		return (xfrm_address_t *)&fl->u.ip6.daddr;
	}
	return NULL;
}

static __inline__
xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
{
	switch (family){
	case AF_INET:
		return (xfrm_address_t *)&fl->u.ip4.saddr;
	case AF_INET6:
		return (xfrm_address_t *)&fl->u.ip6.saddr;
	}
	return NULL;
}

static __inline__
void xfrm_flowi_addr_get(const struct flowi *fl,
			 xfrm_address_t *saddr, xfrm_address_t *daddr,
			 unsigned short family)
{
	switch(family) {
	case AF_INET:
		memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
		memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
		break;
	case AF_INET6:
		saddr->in6 = fl->u.ip6.saddr;
		daddr->in6 = fl->u.ip6.daddr;
		break;
	}
}

static __inline__ int
__xfrm4_state_addr_check(const struct xfrm_state *x,
			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
{
	if (daddr->a4 == x->id.daddr.a4 &&
	    (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
		return 1;
	return 0;
}

static __inline__ int
__xfrm6_state_addr_check(const struct xfrm_state *x,
			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
{
	if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
	    (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
	     ipv6_addr_any((struct in6_addr *)saddr) || 
	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
		return 1;
	return 0;
}

static __inline__ int
xfrm_state_addr_check(const struct xfrm_state *x,
		      const xfrm_address_t *daddr, const xfrm_address_t *saddr,
		      unsigned short family)
{
	switch (family) {
	case AF_INET:
		return __xfrm4_state_addr_check(x, daddr, saddr);
	case AF_INET6:
		return __xfrm6_state_addr_check(x, daddr, saddr);
	}
	return 0;
}

static __inline__ int
xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
			   unsigned short family)
{
	switch (family) {
	case AF_INET:
		return __xfrm4_state_addr_check(x,
						(const xfrm_address_t *)&fl->u.ip4.daddr,
						(const xfrm_address_t *)&fl->u.ip4.saddr);
	case AF_INET6:
		return __xfrm6_state_addr_check(x,
						(const xfrm_address_t *)&fl->u.ip6.daddr,
						(const xfrm_address_t *)&fl->u.ip6.saddr);
	}
	return 0;
}

static inline int xfrm_state_kern(const struct xfrm_state *x)
{
	return atomic_read(&x->tunnel_users);
}

static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
{
	return (!userproto || proto == userproto ||
		(userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
						  proto == IPPROTO_ESP ||
						  proto == IPPROTO_COMP)));
}

/*
 * xfrm algorithm information
 */
struct xfrm_algo_aead_info {
	char *geniv;
	u16 icv_truncbits;
};

struct xfrm_algo_auth_info {
	u16 icv_truncbits;
	u16 icv_fullbits;
};

struct xfrm_algo_encr_info {
	char *geniv;
	u16 blockbits;
	u16 defkeybits;
};

struct xfrm_algo_comp_info {
	u16 threshold;
};

struct xfrm_algo_desc {
	char *name;
	char *compat;
	u8 available:1;
	u8 pfkey_supported:1;
	union {
		struct xfrm_algo_aead_info aead;
		struct xfrm_algo_auth_info auth;
		struct xfrm_algo_encr_info encr;
		struct xfrm_algo_comp_info comp;
	} uinfo;
	struct sadb_alg desc;
};

/* XFRM protocol handlers.  */
struct xfrm4_protocol {
	int (*handler)(struct sk_buff *skb);
	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
			     int encap_type);
	int (*cb_handler)(struct sk_buff *skb, int err);
	int (*err_handler)(struct sk_buff *skb, u32 info);

	struct xfrm4_protocol __rcu *next;
	int priority;
};

struct xfrm6_protocol {
	int (*handler)(struct sk_buff *skb);
	int (*cb_handler)(struct sk_buff *skb, int err);
	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
			   u8 type, u8 code, int offset, __be32 info);

	struct xfrm6_protocol __rcu *next;
	int priority;
};

/* XFRM tunnel handlers.  */
struct xfrm_tunnel {
	int (*handler)(struct sk_buff *skb);
	int (*err_handler)(struct sk_buff *skb, u32 info);

	struct xfrm_tunnel __rcu *next;
	int priority;
};

struct xfrm6_tunnel {
	int (*handler)(struct sk_buff *skb);
	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
			   u8 type, u8 code, int offset, __be32 info);
	struct xfrm6_tunnel __rcu *next;
	int priority;
};

void xfrm_init(void);
void xfrm4_init(void);
int xfrm_state_init(struct net *net);
void xfrm_state_fini(struct net *net);
void xfrm4_state_init(void);
void xfrm4_protocol_init(void);
#ifdef CONFIG_XFRM
int xfrm6_init(void);
void xfrm6_fini(void);
int xfrm6_state_init(void);
void xfrm6_state_fini(void);
int xfrm6_protocol_init(void);
void xfrm6_protocol_fini(void);
#else
static inline int xfrm6_init(void)
{
	return 0;
}
static inline void xfrm6_fini(void)
{
	;
}
#endif

#ifdef CONFIG_XFRM_STATISTICS
int xfrm_proc_init(struct net *net);
void xfrm_proc_fini(struct net *net);
#endif

int xfrm_sysctl_init(struct net *net);
#ifdef CONFIG_SYSCTL
void xfrm_sysctl_fini(struct net *net);
#else
static inline void xfrm_sysctl_fini(struct net *net)
{
}
#endif

void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
			  struct xfrm_address_filter *filter);
int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
		    int (*func)(struct xfrm_state *, int, void*), void *);
void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
struct xfrm_state *xfrm_state_alloc(struct net *net);
struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
				   const xfrm_address_t *saddr,
				   const struct flowi *fl,
				   struct xfrm_tmpl *tmpl,
				   struct xfrm_policy *pol, int *err,
				   unsigned short family);
struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
				       xfrm_address_t *daddr,
				       xfrm_address_t *saddr,
				       unsigned short family,
				       u8 mode, u8 proto, u32 reqid);
struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
					      unsigned short family);
int xfrm_state_check_expire(struct xfrm_state *x);
void xfrm_state_insert(struct xfrm_state *x);
int xfrm_state_add(struct xfrm_state *x);
int xfrm_state_update(struct xfrm_state *x);
struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
				     const xfrm_address_t *daddr, __be32 spi,
				     u8 proto, unsigned short family);
struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
					    const xfrm_address_t *daddr,
					    const xfrm_address_t *saddr,
					    u8 proto,
					    unsigned short family);
#ifdef CONFIG_XFRM_SUB_POLICY
int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
		   unsigned short family, struct net *net);
int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
		    unsigned short family);
#else
static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
				 int n, unsigned short family, struct net *net)
{
	return -ENOSYS;
}

static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src,
				  int n, unsigned short family)
{
	return -ENOSYS;
}
#endif

struct xfrmk_sadinfo {
	u32 sadhcnt; /* current hash bkts */
	u32 sadhmcnt; /* max allowed hash bkts */
	u32 sadcnt; /* current running count */
};

struct xfrmk_spdinfo {
	u32 incnt;
	u32 outcnt;
	u32 fwdcnt;
	u32 inscnt;
	u32 outscnt;
	u32 fwdscnt;
	u32 spdhcnt;
	u32 spdhmcnt;
};

struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
int xfrm_state_delete(struct xfrm_state *x);
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid);
void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);