diff options
| -rw-r--r-- | include/net/xfrm.h | 1 | ||||
| -rw-r--r-- | net/ipv4/esp4.c | 128 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 7 |
3 files changed, 38 insertions, 98 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 004e645f3e18..8d362c49b8a9 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -233,7 +233,6 @@ struct xfrm_type | |||
| 233 | int (*init_state)(struct xfrm_state *x); | 233 | int (*init_state)(struct xfrm_state *x); |
| 234 | void (*destructor)(struct xfrm_state *); | 234 | void (*destructor)(struct xfrm_state *); |
| 235 | int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); | 235 | int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); |
| 236 | int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); | ||
| 237 | int (*output)(struct xfrm_state *, struct sk_buff *pskb); | 236 | int (*output)(struct xfrm_state *, struct sk_buff *pskb); |
| 238 | /* Estimate maximal size of result of transformation of a dgram */ | 237 | /* Estimate maximal size of result of transformation of a dgram */ |
| 239 | u32 (*get_max_size)(struct xfrm_state *, int size); | 238 | u32 (*get_max_size)(struct xfrm_state *, int size); |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 3f47419cb9c5..09590f356086 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
| @@ -12,13 +12,6 @@ | |||
| 12 | #include <net/protocol.h> | 12 | #include <net/protocol.h> |
| 13 | #include <net/udp.h> | 13 | #include <net/udp.h> |
| 14 | 14 | ||
| 15 | /* decapsulation data for use when post-processing */ | ||
| 16 | struct esp_decap_data { | ||
| 17 | xfrm_address_t saddr; | ||
| 18 | __u16 sport; | ||
| 19 | __u8 proto; | ||
| 20 | }; | ||
| 21 | |||
| 22 | static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | 15 | static int esp_output(struct xfrm_state *x, struct sk_buff *skb) |
| 23 | { | 16 | { |
| 24 | int err; | 17 | int err; |
| @@ -210,25 +203,47 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc | |||
| 210 | 203 | ||
| 211 | /* ... check padding bits here. Silly. :-) */ | 204 | /* ... check padding bits here. Silly. :-) */ |
| 212 | 205 | ||
| 213 | if (x->encap && decap && decap->decap_type) { | 206 | if (x->encap) { |
| 214 | struct esp_decap_data *encap_data; | 207 | struct xfrm_encap_tmpl *encap = x->encap; |
| 215 | struct udphdr *uh = (struct udphdr *) (iph+1); | 208 | struct udphdr *uh; |
| 216 | |||
| 217 | encap_data = (struct esp_decap_data *) (decap->decap_data); | ||
| 218 | encap_data->proto = 0; | ||
| 219 | |||
| 220 | switch (decap->decap_type) { | ||
| 221 | case UDP_ENCAP_ESPINUDP: | ||
| 222 | case UDP_ENCAP_ESPINUDP_NON_IKE: | ||
| 223 | encap_data->proto = AF_INET; | ||
| 224 | encap_data->saddr.a4 = iph->saddr; | ||
| 225 | encap_data->sport = uh->source; | ||
| 226 | encap_len = (void*)esph - (void*)uh; | ||
| 227 | break; | ||
| 228 | 209 | ||
| 229 | default: | 210 | if (encap->encap_type != decap->decap_type) |
| 230 | goto out; | 211 | goto out; |
| 212 | |||
| 213 | uh = (struct udphdr *)(iph + 1); | ||
| 214 | encap_len = (void*)esph - (void*)uh; | ||
| 215 | |||
| 216 | /* | ||
| 217 | * 1) if the NAT-T peer's IP or port changed then | ||
| 218 | * advertize the change to the keying daemon. | ||
| 219 | * This is an inbound SA, so just compare | ||
| 220 | * SRC ports. | ||
| 221 | */ | ||
| 222 | if (iph->saddr != x->props.saddr.a4 || | ||
| 223 | uh->source != encap->encap_sport) { | ||
| 224 | xfrm_address_t ipaddr; | ||
| 225 | |||
| 226 | ipaddr.a4 = iph->saddr; | ||
| 227 | km_new_mapping(x, &ipaddr, uh->source); | ||
| 228 | |||
| 229 | /* XXX: perhaps add an extra | ||
| 230 | * policy check here, to see | ||
| 231 | * if we should allow or | ||
| 232 | * reject a packet from a | ||
| 233 | * different source | ||
| 234 | * address/port. | ||
| 235 | */ | ||
| 231 | } | 236 | } |
| 237 | |||
| 238 | /* | ||
| 239 | * 2) ignore UDP/TCP checksums in case | ||
| 240 | * of NAT-T in Transport Mode, or | ||
| 241 | * perform other post-processing fixes | ||
| 242 | * as per draft-ietf-ipsec-udp-encaps-06, | ||
| 243 | * section 3.1.2 | ||
| 244 | */ | ||
| 245 | if (!x->props.mode) | ||
| 246 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 232 | } | 247 | } |
| 233 | 248 | ||
| 234 | iph->protocol = nexthdr[1]; | 249 | iph->protocol = nexthdr[1]; |
| @@ -245,63 +260,6 @@ out: | |||
| 245 | return -EINVAL; | 260 | return -EINVAL; |
| 246 | } | 261 | } |
| 247 | 262 | ||
| 248 | static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) | ||
| 249 | { | ||
| 250 | |||
| 251 | if (x->encap) { | ||
| 252 | struct xfrm_encap_tmpl *encap; | ||
| 253 | struct esp_decap_data *decap_data; | ||
| 254 | |||
| 255 | encap = x->encap; | ||
| 256 | decap_data = (struct esp_decap_data *)(decap->decap_data); | ||
| 257 | |||
| 258 | /* first, make sure that the decap type == the encap type */ | ||
| 259 | if (encap->encap_type != decap->decap_type) | ||
| 260 | return -EINVAL; | ||
| 261 | |||
| 262 | switch (encap->encap_type) { | ||
| 263 | default: | ||
| 264 | case UDP_ENCAP_ESPINUDP: | ||
| 265 | case UDP_ENCAP_ESPINUDP_NON_IKE: | ||
| 266 | /* | ||
| 267 | * 1) if the NAT-T peer's IP or port changed then | ||
| 268 | * advertize the change to the keying daemon. | ||
| 269 | * This is an inbound SA, so just compare | ||
| 270 | * SRC ports. | ||
| 271 | */ | ||
| 272 | if (decap_data->proto == AF_INET && | ||
| 273 | (decap_data->saddr.a4 != x->props.saddr.a4 || | ||
| 274 | decap_data->sport != encap->encap_sport)) { | ||
| 275 | xfrm_address_t ipaddr; | ||
| 276 | |||
| 277 | ipaddr.a4 = decap_data->saddr.a4; | ||
| 278 | km_new_mapping(x, &ipaddr, decap_data->sport); | ||
| 279 | |||
| 280 | /* XXX: perhaps add an extra | ||
| 281 | * policy check here, to see | ||
| 282 | * if we should allow or | ||
| 283 | * reject a packet from a | ||
| 284 | * different source | ||
| 285 | * address/port. | ||
| 286 | */ | ||
| 287 | } | ||
| 288 | |||
| 289 | /* | ||
| 290 | * 2) ignore UDP/TCP checksums in case | ||
| 291 | * of NAT-T in Transport Mode, or | ||
| 292 | * perform other post-processing fixes | ||
| 293 | * as per * draft-ietf-ipsec-udp-encaps-06, | ||
| 294 | * section 3.1.2 | ||
| 295 | */ | ||
| 296 | if (!x->props.mode) | ||
| 297 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 298 | |||
| 299 | break; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) | 263 | static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) |
| 306 | { | 264 | { |
| 307 | struct esp_data *esp = x->data; | 265 | struct esp_data *esp = x->data; |
| @@ -457,7 +415,6 @@ static struct xfrm_type esp_type = | |||
| 457 | .destructor = esp_destroy, | 415 | .destructor = esp_destroy, |
| 458 | .get_max_size = esp4_get_max_size, | 416 | .get_max_size = esp4_get_max_size, |
| 459 | .input = esp_input, | 417 | .input = esp_input, |
| 460 | .post_input = esp_post_input, | ||
| 461 | .output = esp_output | 418 | .output = esp_output |
| 462 | }; | 419 | }; |
| 463 | 420 | ||
| @@ -469,15 +426,6 @@ static struct net_protocol esp4_protocol = { | |||
| 469 | 426 | ||
| 470 | static int __init esp4_init(void) | 427 | static int __init esp4_init(void) |
| 471 | { | 428 | { |
| 472 | struct xfrm_decap_state decap; | ||
| 473 | |||
| 474 | if (sizeof(struct esp_decap_data) > | ||
| 475 | sizeof(decap.decap_data)) { | ||
| 476 | extern void decap_data_too_small(void); | ||
| 477 | |||
| 478 | decap_data_too_small(); | ||
| 479 | } | ||
| 480 | |||
| 481 | if (xfrm_register_type(&esp_type, AF_INET) < 0) { | 429 | if (xfrm_register_type(&esp_type, AF_INET) < 0) { |
| 482 | printk(KERN_INFO "ip esp init: can't add xfrm type\n"); | 430 | printk(KERN_INFO "ip esp init: can't add xfrm type\n"); |
| 483 | return -EAGAIN; | 431 | return -EAGAIN; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8206025d8e46..ae62054a9fc4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -996,13 +996,6 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 996 | struct sec_decap_state *xvec = &(skb->sp->x[i]); | 996 | struct sec_decap_state *xvec = &(skb->sp->x[i]); |
| 997 | if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) | 997 | if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) |
| 998 | return 0; | 998 | return 0; |
| 999 | |||
| 1000 | /* If there is a post_input processor, try running it */ | ||
| 1001 | if (xvec->xvec->type->post_input && | ||
| 1002 | (xvec->xvec->type->post_input)(xvec->xvec, | ||
| 1003 | &(xvec->decap), | ||
| 1004 | skb) != 0) | ||
| 1005 | return 0; | ||
| 1006 | } | 999 | } |
| 1007 | } | 1000 | } |
| 1008 | 1001 | ||
