2 * xfrm6_state.c: based on xfrm4_state.c
6 * Kazunori MIYAZAWA @USAGI
7 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
9 * YOSHIFUJI Hideaki @USAGI
10 * Split up af-specific portion
15 #include <linux/pfkeyv2.h>
16 #include <linux/ipsec.h>
18 #include <net/addrconf.h>
20 static struct xfrm_state_afinfo xfrm6_state_afinfo
;
23 __xfrm6_init_tempsel(struct xfrm_state
*x
, struct flowi
*fl
,
24 struct xfrm_tmpl
*tmpl
,
25 xfrm_address_t
*daddr
, xfrm_address_t
*saddr
)
27 /* Initialize temporary selector matching only
28 * to current session. */
29 ipv6_addr_copy((struct in6_addr
*)&x
->sel
.daddr
, &fl
->fl6_dst
);
30 ipv6_addr_copy((struct in6_addr
*)&x
->sel
.saddr
, &fl
->fl6_src
);
31 x
->sel
.dport
= xfrm_flowi_dport(fl
);
32 x
->sel
.dport_mask
= htons(0xffff);
33 x
->sel
.sport
= xfrm_flowi_sport(fl
);
34 x
->sel
.sport_mask
= htons(0xffff);
35 x
->sel
.prefixlen_d
= 128;
36 x
->sel
.prefixlen_s
= 128;
37 x
->sel
.proto
= fl
->proto
;
38 x
->sel
.ifindex
= fl
->oif
;
40 if (ipv6_addr_any((struct in6_addr
*)&x
->id
.daddr
))
41 memcpy(&x
->id
.daddr
, daddr
, sizeof(x
->sel
.daddr
));
42 memcpy(&x
->props
.saddr
, &tmpl
->saddr
, sizeof(x
->props
.saddr
));
43 if (ipv6_addr_any((struct in6_addr
*)&x
->props
.saddr
))
44 memcpy(&x
->props
.saddr
, saddr
, sizeof(x
->props
.saddr
));
45 x
->props
.mode
= tmpl
->mode
;
46 x
->props
.reqid
= tmpl
->reqid
;
47 x
->props
.family
= AF_INET6
;
51 __xfrm6_state_sort(struct xfrm_state
**dst
, struct xfrm_state
**src
, int n
)
56 /* Rule 1: select IPsec transport except AH */
57 for (i
= 0; i
< n
; i
++) {
58 if (src
[i
]->props
.mode
== XFRM_MODE_TRANSPORT
&&
59 src
[i
]->id
.proto
!= IPPROTO_AH
) {
67 /* Rule 2: select MIPv6 RO or inbound trigger */
68 #ifdef CONFIG_IPV6_MIP6
69 for (i
= 0; i
< n
; i
++) {
71 (src
[i
]->props
.mode
== XFRM_MODE_ROUTEOPTIMIZATION
||
72 src
[i
]->props
.mode
== XFRM_MODE_IN_TRIGGER
)) {
81 /* Rule 3: select IPsec transport AH */
82 for (i
= 0; i
< n
; i
++) {
84 src
[i
]->props
.mode
== XFRM_MODE_TRANSPORT
&&
85 src
[i
]->id
.proto
== IPPROTO_AH
) {
93 /* Rule 4: select IPsec tunnel */
94 for (i
= 0; i
< n
; i
++) {
96 src
[i
]->props
.mode
== XFRM_MODE_TUNNEL
) {
105 for (i
= 0; i
< n
; i
++) {
117 __xfrm6_tmpl_sort(struct xfrm_tmpl
**dst
, struct xfrm_tmpl
**src
, int n
)
122 /* Rule 1: select IPsec transport */
123 for (i
= 0; i
< n
; i
++) {
124 if (src
[i
]->mode
== XFRM_MODE_TRANSPORT
) {
132 /* Rule 2: select MIPv6 RO or inbound trigger */
133 #ifdef CONFIG_IPV6_MIP6
134 for (i
= 0; i
< n
; i
++) {
136 (src
[i
]->mode
== XFRM_MODE_ROUTEOPTIMIZATION
||
137 src
[i
]->mode
== XFRM_MODE_IN_TRIGGER
)) {
146 /* Rule 3: select IPsec tunnel */
147 for (i
= 0; i
< n
; i
++) {
149 src
[i
]->mode
== XFRM_MODE_TUNNEL
) {
158 for (i
= 0; i
< n
; i
++) {
169 static struct xfrm_state_afinfo xfrm6_state_afinfo
= {
171 .init_tempsel
= __xfrm6_init_tempsel
,
172 .tmpl_sort
= __xfrm6_tmpl_sort
,
173 .state_sort
= __xfrm6_state_sort
,
174 .output
= xfrm6_output
,
177 void __init
xfrm6_state_init(void)
179 xfrm_state_register_afinfo(&xfrm6_state_afinfo
);
182 void xfrm6_state_fini(void)
184 xfrm_state_unregister_afinfo(&xfrm6_state_afinfo
);