diff options
Diffstat (limited to 'net/sctp/input.c')
| -rw-r--r-- | net/sctp/input.c | 45 |
1 files changed, 12 insertions, 33 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 5e085e041a6e..742be9171b7d 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -351,7 +351,6 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
| 351 | * | 351 | * |
| 352 | */ | 352 | */ |
| 353 | void sctp_icmp_proto_unreachable(struct sock *sk, | 353 | void sctp_icmp_proto_unreachable(struct sock *sk, |
| 354 | struct sctp_endpoint *ep, | ||
| 355 | struct sctp_association *asoc, | 354 | struct sctp_association *asoc, |
| 356 | struct sctp_transport *t) | 355 | struct sctp_transport *t) |
| 357 | { | 356 | { |
| @@ -367,7 +366,6 @@ void sctp_icmp_proto_unreachable(struct sock *sk, | |||
| 367 | /* Common lookup code for icmp/icmpv6 error handler. */ | 366 | /* Common lookup code for icmp/icmpv6 error handler. */ |
| 368 | struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | 367 | struct sock *sctp_err_lookup(int family, struct sk_buff *skb, |
| 369 | struct sctphdr *sctphdr, | 368 | struct sctphdr *sctphdr, |
| 370 | struct sctp_endpoint **epp, | ||
| 371 | struct sctp_association **app, | 369 | struct sctp_association **app, |
| 372 | struct sctp_transport **tpp) | 370 | struct sctp_transport **tpp) |
| 373 | { | 371 | { |
| @@ -375,11 +373,10 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
| 375 | union sctp_addr daddr; | 373 | union sctp_addr daddr; |
| 376 | struct sctp_af *af; | 374 | struct sctp_af *af; |
| 377 | struct sock *sk = NULL; | 375 | struct sock *sk = NULL; |
| 378 | struct sctp_endpoint *ep = NULL; | ||
| 379 | struct sctp_association *asoc = NULL; | 376 | struct sctp_association *asoc = NULL; |
| 380 | struct sctp_transport *transport = NULL; | 377 | struct sctp_transport *transport = NULL; |
| 381 | 378 | ||
| 382 | *app = NULL; *epp = NULL; *tpp = NULL; | 379 | *app = NULL; *tpp = NULL; |
| 383 | 380 | ||
| 384 | af = sctp_get_af_specific(family); | 381 | af = sctp_get_af_specific(family); |
| 385 | if (unlikely(!af)) { | 382 | if (unlikely(!af)) { |
| @@ -394,26 +391,15 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
| 394 | * packet. | 391 | * packet. |
| 395 | */ | 392 | */ |
| 396 | asoc = __sctp_lookup_association(&saddr, &daddr, &transport); | 393 | asoc = __sctp_lookup_association(&saddr, &daddr, &transport); |
| 397 | if (!asoc) { | 394 | if (!asoc) |
| 398 | /* If there is no matching association, see if it matches any | 395 | return NULL; |
| 399 | * endpoint. This may happen for an ICMP error generated in | ||
| 400 | * response to an INIT_ACK. | ||
| 401 | */ | ||
| 402 | ep = __sctp_rcv_lookup_endpoint(&daddr); | ||
| 403 | if (!ep) { | ||
| 404 | return NULL; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | 396 | ||
| 408 | if (asoc) { | 397 | sk = asoc->base.sk; |
| 409 | sk = asoc->base.sk; | ||
| 410 | 398 | ||
| 411 | if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) { | 399 | if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) { |
| 412 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 400 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
| 413 | goto out; | 401 | goto out; |
| 414 | } | 402 | } |
| 415 | } else | ||
| 416 | sk = ep->base.sk; | ||
| 417 | 403 | ||
| 418 | sctp_bh_lock_sock(sk); | 404 | sctp_bh_lock_sock(sk); |
| 419 | 405 | ||
| @@ -423,7 +409,6 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
| 423 | if (sock_owned_by_user(sk)) | 409 | if (sock_owned_by_user(sk)) |
| 424 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); | 410 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); |
| 425 | 411 | ||
| 426 | *epp = ep; | ||
| 427 | *app = asoc; | 412 | *app = asoc; |
| 428 | *tpp = transport; | 413 | *tpp = transport; |
| 429 | return sk; | 414 | return sk; |
| @@ -432,21 +417,16 @@ out: | |||
| 432 | sock_put(sk); | 417 | sock_put(sk); |
| 433 | if (asoc) | 418 | if (asoc) |
| 434 | sctp_association_put(asoc); | 419 | sctp_association_put(asoc); |
| 435 | if (ep) | ||
| 436 | sctp_endpoint_put(ep); | ||
| 437 | return NULL; | 420 | return NULL; |
| 438 | } | 421 | } |
| 439 | 422 | ||
| 440 | /* Common cleanup code for icmp/icmpv6 error handler. */ | 423 | /* Common cleanup code for icmp/icmpv6 error handler. */ |
| 441 | void sctp_err_finish(struct sock *sk, struct sctp_endpoint *ep, | 424 | void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) |
| 442 | struct sctp_association *asoc) | ||
| 443 | { | 425 | { |
| 444 | sctp_bh_unlock_sock(sk); | 426 | sctp_bh_unlock_sock(sk); |
| 445 | sock_put(sk); | 427 | sock_put(sk); |
| 446 | if (asoc) | 428 | if (asoc) |
| 447 | sctp_association_put(asoc); | 429 | sctp_association_put(asoc); |
| 448 | if (ep) | ||
| 449 | sctp_endpoint_put(ep); | ||
| 450 | } | 430 | } |
| 451 | 431 | ||
| 452 | /* | 432 | /* |
| @@ -471,7 +451,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 471 | int type = skb->h.icmph->type; | 451 | int type = skb->h.icmph->type; |
| 472 | int code = skb->h.icmph->code; | 452 | int code = skb->h.icmph->code; |
| 473 | struct sock *sk; | 453 | struct sock *sk; |
| 474 | struct sctp_endpoint *ep; | ||
| 475 | struct sctp_association *asoc; | 454 | struct sctp_association *asoc; |
| 476 | struct sctp_transport *transport; | 455 | struct sctp_transport *transport; |
| 477 | struct inet_sock *inet; | 456 | struct inet_sock *inet; |
| @@ -488,7 +467,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 488 | savesctp = skb->h.raw; | 467 | savesctp = skb->h.raw; |
| 489 | skb->nh.iph = iph; | 468 | skb->nh.iph = iph; |
| 490 | skb->h.raw = (char *)sh; | 469 | skb->h.raw = (char *)sh; |
| 491 | sk = sctp_err_lookup(AF_INET, skb, sh, &ep, &asoc, &transport); | 470 | sk = sctp_err_lookup(AF_INET, skb, sh, &asoc, &transport); |
| 492 | /* Put back, the original pointers. */ | 471 | /* Put back, the original pointers. */ |
| 493 | skb->nh.raw = saveip; | 472 | skb->nh.raw = saveip; |
| 494 | skb->h.raw = savesctp; | 473 | skb->h.raw = savesctp; |
| @@ -515,7 +494,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 515 | } | 494 | } |
| 516 | else { | 495 | else { |
| 517 | if (ICMP_PROT_UNREACH == code) { | 496 | if (ICMP_PROT_UNREACH == code) { |
| 518 | sctp_icmp_proto_unreachable(sk, ep, asoc, | 497 | sctp_icmp_proto_unreachable(sk, asoc, |
| 519 | transport); | 498 | transport); |
| 520 | goto out_unlock; | 499 | goto out_unlock; |
| 521 | } | 500 | } |
| @@ -544,7 +523,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 544 | } | 523 | } |
| 545 | 524 | ||
| 546 | out_unlock: | 525 | out_unlock: |
| 547 | sctp_err_finish(sk, ep, asoc); | 526 | sctp_err_finish(sk, asoc); |
| 548 | } | 527 | } |
| 549 | 528 | ||
| 550 | /* | 529 | /* |
