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