diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/sctp/input.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r-- | net/sctp/input.c | 150 |
1 files changed, 57 insertions, 93 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 8bd3c279427..b7692aab6e9 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -66,15 +66,12 @@ | |||
66 | 66 | ||
67 | /* Forward declarations for internal helpers. */ | 67 | /* Forward declarations for internal helpers. */ |
68 | static int sctp_rcv_ootb(struct sk_buff *); | 68 | static int sctp_rcv_ootb(struct sk_buff *); |
69 | static struct sctp_association *__sctp_rcv_lookup(struct net *net, | 69 | static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, |
70 | struct sk_buff *skb, | ||
71 | const union sctp_addr *paddr, | ||
72 | const union sctp_addr *laddr, | 70 | const union sctp_addr *laddr, |
71 | const union sctp_addr *paddr, | ||
73 | struct sctp_transport **transportp); | 72 | struct sctp_transport **transportp); |
74 | static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, | 73 | static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr); |
75 | const union sctp_addr *laddr); | ||
76 | static struct sctp_association *__sctp_lookup_association( | 74 | static struct sctp_association *__sctp_lookup_association( |
77 | struct net *net, | ||
78 | const union sctp_addr *local, | 75 | const union sctp_addr *local, |
79 | const union sctp_addr *peer, | 76 | const union sctp_addr *peer, |
80 | struct sctp_transport **pt); | 77 | struct sctp_transport **pt); |
@@ -83,7 +80,7 @@ static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb); | |||
83 | 80 | ||
84 | 81 | ||
85 | /* Calculate the SCTP checksum of an SCTP packet. */ | 82 | /* Calculate the SCTP checksum of an SCTP packet. */ |
86 | static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb) | 83 | static inline int sctp_rcv_checksum(struct sk_buff *skb) |
87 | { | 84 | { |
88 | struct sctphdr *sh = sctp_hdr(skb); | 85 | struct sctphdr *sh = sctp_hdr(skb); |
89 | __le32 cmp = sh->checksum; | 86 | __le32 cmp = sh->checksum; |
@@ -99,7 +96,7 @@ static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb) | |||
99 | 96 | ||
100 | if (val != cmp) { | 97 | if (val != cmp) { |
101 | /* CRC failure, dump it. */ | 98 | /* CRC failure, dump it. */ |
102 | SCTP_INC_STATS_BH(net, SCTP_MIB_CHECKSUMERRORS); | 99 | SCTP_INC_STATS_BH(SCTP_MIB_CHECKSUMERRORS); |
103 | return -1; | 100 | return -1; |
104 | } | 101 | } |
105 | return 0; | 102 | return 0; |
@@ -108,7 +105,7 @@ static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb) | |||
108 | struct sctp_input_cb { | 105 | struct sctp_input_cb { |
109 | union { | 106 | union { |
110 | struct inet_skb_parm h4; | 107 | struct inet_skb_parm h4; |
111 | #if IS_ENABLED(CONFIG_IPV6) | 108 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
112 | struct inet6_skb_parm h6; | 109 | struct inet6_skb_parm h6; |
113 | #endif | 110 | #endif |
114 | } header; | 111 | } header; |
@@ -132,12 +129,11 @@ int sctp_rcv(struct sk_buff *skb) | |||
132 | union sctp_addr dest; | 129 | union sctp_addr dest; |
133 | int family; | 130 | int family; |
134 | struct sctp_af *af; | 131 | struct sctp_af *af; |
135 | struct net *net = dev_net(skb->dev); | ||
136 | 132 | ||
137 | if (skb->pkt_type!=PACKET_HOST) | 133 | if (skb->pkt_type!=PACKET_HOST) |
138 | goto discard_it; | 134 | goto discard_it; |
139 | 135 | ||
140 | SCTP_INC_STATS_BH(net, SCTP_MIB_INSCTPPACKS); | 136 | SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS); |
141 | 137 | ||
142 | if (skb_linearize(skb)) | 138 | if (skb_linearize(skb)) |
143 | goto discard_it; | 139 | goto discard_it; |
@@ -149,7 +145,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
149 | if (skb->len < sizeof(struct sctphdr)) | 145 | if (skb->len < sizeof(struct sctphdr)) |
150 | goto discard_it; | 146 | goto discard_it; |
151 | if (!sctp_checksum_disable && !skb_csum_unnecessary(skb) && | 147 | if (!sctp_checksum_disable && !skb_csum_unnecessary(skb) && |
152 | sctp_rcv_checksum(net, skb) < 0) | 148 | sctp_rcv_checksum(skb) < 0) |
153 | goto discard_it; | 149 | goto discard_it; |
154 | 150 | ||
155 | skb_pull(skb, sizeof(struct sctphdr)); | 151 | skb_pull(skb, sizeof(struct sctphdr)); |
@@ -182,10 +178,10 @@ int sctp_rcv(struct sk_buff *skb) | |||
182 | !af->addr_valid(&dest, NULL, skb)) | 178 | !af->addr_valid(&dest, NULL, skb)) |
183 | goto discard_it; | 179 | goto discard_it; |
184 | 180 | ||
185 | asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport); | 181 | asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); |
186 | 182 | ||
187 | if (!asoc) | 183 | if (!asoc) |
188 | ep = __sctp_rcv_lookup_endpoint(net, &dest); | 184 | ep = __sctp_rcv_lookup_endpoint(&dest); |
189 | 185 | ||
190 | /* Retrieve the common input handling substructure. */ | 186 | /* Retrieve the common input handling substructure. */ |
191 | rcvr = asoc ? &asoc->base : &ep->base; | 187 | rcvr = asoc ? &asoc->base : &ep->base; |
@@ -204,7 +200,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
204 | sctp_endpoint_put(ep); | 200 | sctp_endpoint_put(ep); |
205 | ep = NULL; | 201 | ep = NULL; |
206 | } | 202 | } |
207 | sk = net->sctp.ctl_sock; | 203 | sk = sctp_get_ctl_sock(); |
208 | ep = sctp_sk(sk)->ep; | 204 | ep = sctp_sk(sk)->ep; |
209 | sctp_endpoint_hold(ep); | 205 | sctp_endpoint_hold(ep); |
210 | rcvr = &ep->base; | 206 | rcvr = &ep->base; |
@@ -220,7 +216,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
220 | */ | 216 | */ |
221 | if (!asoc) { | 217 | if (!asoc) { |
222 | if (sctp_rcv_ootb(skb)) { | 218 | if (sctp_rcv_ootb(skb)) { |
223 | SCTP_INC_STATS_BH(net, SCTP_MIB_OUTOFBLUES); | 219 | SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES); |
224 | goto discard_release; | 220 | goto discard_release; |
225 | } | 221 | } |
226 | } | 222 | } |
@@ -276,9 +272,9 @@ int sctp_rcv(struct sk_buff *skb) | |||
276 | skb = NULL; /* sctp_chunk_free already freed the skb */ | 272 | skb = NULL; /* sctp_chunk_free already freed the skb */ |
277 | goto discard_release; | 273 | goto discard_release; |
278 | } | 274 | } |
279 | SCTP_INC_STATS_BH(net, SCTP_MIB_IN_PKT_BACKLOG); | 275 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); |
280 | } else { | 276 | } else { |
281 | SCTP_INC_STATS_BH(net, SCTP_MIB_IN_PKT_SOFTIRQ); | 277 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ); |
282 | sctp_inq_push(&chunk->rcvr->inqueue, chunk); | 278 | sctp_inq_push(&chunk->rcvr->inqueue, chunk); |
283 | } | 279 | } |
284 | 280 | ||
@@ -293,7 +289,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
293 | return 0; | 289 | return 0; |
294 | 290 | ||
295 | discard_it: | 291 | discard_it: |
296 | SCTP_INC_STATS_BH(net, SCTP_MIB_IN_PKT_DISCARDS); | 292 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_DISCARDS); |
297 | kfree_skb(skb); | 293 | kfree_skb(skb); |
298 | return 0; | 294 | return 0; |
299 | 295 | ||
@@ -346,7 +342,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
346 | sctp_bh_lock_sock(sk); | 342 | sctp_bh_lock_sock(sk); |
347 | 343 | ||
348 | if (sock_owned_by_user(sk)) { | 344 | if (sock_owned_by_user(sk)) { |
349 | if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) | 345 | if (sk_add_backlog(sk, skb)) |
350 | sctp_chunk_free(chunk); | 346 | sctp_chunk_free(chunk); |
351 | else | 347 | else |
352 | backloged = 1; | 348 | backloged = 1; |
@@ -380,7 +376,7 @@ static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) | |||
380 | struct sctp_ep_common *rcvr = chunk->rcvr; | 376 | struct sctp_ep_common *rcvr = chunk->rcvr; |
381 | int ret; | 377 | int ret; |
382 | 378 | ||
383 | ret = sk_add_backlog(sk, skb, sk->sk_rcvbuf); | 379 | ret = sk_add_backlog(sk, skb); |
384 | if (!ret) { | 380 | if (!ret) { |
385 | /* Hold the assoc/ep while hanging on the backlog queue. | 381 | /* Hold the assoc/ep while hanging on the backlog queue. |
386 | * This way, we know structures we need will not disappear | 382 | * This way, we know structures we need will not disappear |
@@ -412,10 +408,10 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
412 | 408 | ||
413 | if (t->param_flags & SPP_PMTUD_ENABLE) { | 409 | if (t->param_flags & SPP_PMTUD_ENABLE) { |
414 | /* Update transports view of the MTU */ | 410 | /* Update transports view of the MTU */ |
415 | sctp_transport_update_pmtu(sk, t, pmtu); | 411 | sctp_transport_update_pmtu(t, pmtu); |
416 | 412 | ||
417 | /* Update association pmtu. */ | 413 | /* Update association pmtu. */ |
418 | sctp_assoc_sync_pmtu(sk, asoc); | 414 | sctp_assoc_sync_pmtu(asoc); |
419 | } | 415 | } |
420 | 416 | ||
421 | /* Retransmit with the new pmtu setting. | 417 | /* Retransmit with the new pmtu setting. |
@@ -427,18 +423,6 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
427 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | 423 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); |
428 | } | 424 | } |
429 | 425 | ||
430 | void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t, | ||
431 | struct sk_buff *skb) | ||
432 | { | ||
433 | struct dst_entry *dst; | ||
434 | |||
435 | if (!t) | ||
436 | return; | ||
437 | dst = sctp_transport_dst_check(t); | ||
438 | if (dst) | ||
439 | dst->ops->redirect(dst, sk, skb); | ||
440 | } | ||
441 | |||
442 | /* | 426 | /* |
443 | * SCTP Implementer's Guide, 2.37 ICMP handling procedures | 427 | * SCTP Implementer's Guide, 2.37 ICMP handling procedures |
444 | * | 428 | * |
@@ -466,13 +450,11 @@ void sctp_icmp_proto_unreachable(struct sock *sk, | |||
466 | } | 450 | } |
467 | 451 | ||
468 | } else { | 452 | } else { |
469 | struct net *net = sock_net(sk); | ||
470 | |||
471 | if (timer_pending(&t->proto_unreach_timer) && | 453 | if (timer_pending(&t->proto_unreach_timer) && |
472 | del_timer(&t->proto_unreach_timer)) | 454 | del_timer(&t->proto_unreach_timer)) |
473 | sctp_association_put(asoc); | 455 | sctp_association_put(asoc); |
474 | 456 | ||
475 | sctp_do_sm(net, SCTP_EVENT_T_OTHER, | 457 | sctp_do_sm(SCTP_EVENT_T_OTHER, |
476 | SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), | 458 | SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), |
477 | asoc->state, asoc->ep, asoc, t, | 459 | asoc->state, asoc->ep, asoc, t, |
478 | GFP_ATOMIC); | 460 | GFP_ATOMIC); |
@@ -480,7 +462,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk, | |||
480 | } | 462 | } |
481 | 463 | ||
482 | /* Common lookup code for icmp/icmpv6 error handler. */ | 464 | /* Common lookup code for icmp/icmpv6 error handler. */ |
483 | struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, | 465 | struct sock *sctp_err_lookup(int family, struct sk_buff *skb, |
484 | struct sctphdr *sctphdr, | 466 | struct sctphdr *sctphdr, |
485 | struct sctp_association **app, | 467 | struct sctp_association **app, |
486 | struct sctp_transport **tpp) | 468 | struct sctp_transport **tpp) |
@@ -509,7 +491,7 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, | |||
509 | /* Look for an association that matches the incoming ICMP error | 491 | /* Look for an association that matches the incoming ICMP error |
510 | * packet. | 492 | * packet. |
511 | */ | 493 | */ |
512 | asoc = __sctp_lookup_association(net, &saddr, &daddr, &transport); | 494 | asoc = __sctp_lookup_association(&saddr, &daddr, &transport); |
513 | if (!asoc) | 495 | if (!asoc) |
514 | return NULL; | 496 | return NULL; |
515 | 497 | ||
@@ -545,7 +527,7 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, | |||
545 | * servers this needs to be solved differently. | 527 | * servers this needs to be solved differently. |
546 | */ | 528 | */ |
547 | if (sock_owned_by_user(sk)) | 529 | if (sock_owned_by_user(sk)) |
548 | NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); | 530 | NET_INC_STATS_BH(&init_net, LINUX_MIB_LOCKDROPPEDICMPS); |
549 | 531 | ||
550 | *app = asoc; | 532 | *app = asoc; |
551 | *tpp = transport; | 533 | *tpp = transport; |
@@ -592,10 +574,9 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
592 | struct inet_sock *inet; | 574 | struct inet_sock *inet; |
593 | sk_buff_data_t saveip, savesctp; | 575 | sk_buff_data_t saveip, savesctp; |
594 | int err; | 576 | int err; |
595 | struct net *net = dev_net(skb->dev); | ||
596 | 577 | ||
597 | if (skb->len < ihlen + 8) { | 578 | if (skb->len < ihlen + 8) { |
598 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); | 579 | ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS); |
599 | return; | 580 | return; |
600 | } | 581 | } |
601 | 582 | ||
@@ -604,12 +585,12 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
604 | savesctp = skb->transport_header; | 585 | savesctp = skb->transport_header; |
605 | skb_reset_network_header(skb); | 586 | skb_reset_network_header(skb); |
606 | skb_set_transport_header(skb, ihlen); | 587 | skb_set_transport_header(skb, ihlen); |
607 | sk = sctp_err_lookup(net, AF_INET, skb, sctp_hdr(skb), &asoc, &transport); | 588 | sk = sctp_err_lookup(AF_INET, skb, sctp_hdr(skb), &asoc, &transport); |
608 | /* Put back, the original values. */ | 589 | /* Put back, the original values. */ |
609 | skb->network_header = saveip; | 590 | skb->network_header = saveip; |
610 | skb->transport_header = savesctp; | 591 | skb->transport_header = savesctp; |
611 | if (!sk) { | 592 | if (!sk) { |
612 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); | 593 | ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS); |
613 | return; | 594 | return; |
614 | } | 595 | } |
615 | /* Warning: The sock lock is held. Remember to call | 596 | /* Warning: The sock lock is held. Remember to call |
@@ -647,10 +628,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
647 | 628 | ||
648 | err = EHOSTUNREACH; | 629 | err = EHOSTUNREACH; |
649 | break; | 630 | break; |
650 | case ICMP_REDIRECT: | ||
651 | sctp_icmp_redirect(sk, transport, skb); | ||
652 | err = 0; | ||
653 | break; | ||
654 | default: | 631 | default: |
655 | goto out_unlock; | 632 | goto out_unlock; |
656 | } | 633 | } |
@@ -730,13 +707,12 @@ discard: | |||
730 | /* Insert endpoint into the hash table. */ | 707 | /* Insert endpoint into the hash table. */ |
731 | static void __sctp_hash_endpoint(struct sctp_endpoint *ep) | 708 | static void __sctp_hash_endpoint(struct sctp_endpoint *ep) |
732 | { | 709 | { |
733 | struct net *net = sock_net(ep->base.sk); | ||
734 | struct sctp_ep_common *epb; | 710 | struct sctp_ep_common *epb; |
735 | struct sctp_hashbucket *head; | 711 | struct sctp_hashbucket *head; |
736 | 712 | ||
737 | epb = &ep->base; | 713 | epb = &ep->base; |
738 | 714 | ||
739 | epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); | 715 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); |
740 | head = &sctp_ep_hashtable[epb->hashent]; | 716 | head = &sctp_ep_hashtable[epb->hashent]; |
741 | 717 | ||
742 | sctp_write_lock(&head->lock); | 718 | sctp_write_lock(&head->lock); |
@@ -755,18 +731,20 @@ void sctp_hash_endpoint(struct sctp_endpoint *ep) | |||
755 | /* Remove endpoint from the hash table. */ | 731 | /* Remove endpoint from the hash table. */ |
756 | static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) | 732 | static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) |
757 | { | 733 | { |
758 | struct net *net = sock_net(ep->base.sk); | ||
759 | struct sctp_hashbucket *head; | 734 | struct sctp_hashbucket *head; |
760 | struct sctp_ep_common *epb; | 735 | struct sctp_ep_common *epb; |
761 | 736 | ||
762 | epb = &ep->base; | 737 | epb = &ep->base; |
763 | 738 | ||
764 | epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); | 739 | if (hlist_unhashed(&epb->node)) |
740 | return; | ||
741 | |||
742 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); | ||
765 | 743 | ||
766 | head = &sctp_ep_hashtable[epb->hashent]; | 744 | head = &sctp_ep_hashtable[epb->hashent]; |
767 | 745 | ||
768 | sctp_write_lock(&head->lock); | 746 | sctp_write_lock(&head->lock); |
769 | hlist_del_init(&epb->node); | 747 | __hlist_del(&epb->node); |
770 | sctp_write_unlock(&head->lock); | 748 | sctp_write_unlock(&head->lock); |
771 | } | 749 | } |
772 | 750 | ||
@@ -779,8 +757,7 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep) | |||
779 | } | 757 | } |
780 | 758 | ||
781 | /* Look up an endpoint. */ | 759 | /* Look up an endpoint. */ |
782 | static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, | 760 | static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr) |
783 | const union sctp_addr *laddr) | ||
784 | { | 761 | { |
785 | struct sctp_hashbucket *head; | 762 | struct sctp_hashbucket *head; |
786 | struct sctp_ep_common *epb; | 763 | struct sctp_ep_common *epb; |
@@ -788,16 +765,16 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, | |||
788 | struct hlist_node *node; | 765 | struct hlist_node *node; |
789 | int hash; | 766 | int hash; |
790 | 767 | ||
791 | hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port)); | 768 | hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port)); |
792 | head = &sctp_ep_hashtable[hash]; | 769 | head = &sctp_ep_hashtable[hash]; |
793 | read_lock(&head->lock); | 770 | read_lock(&head->lock); |
794 | sctp_for_each_hentry(epb, node, &head->chain) { | 771 | sctp_for_each_hentry(epb, node, &head->chain) { |
795 | ep = sctp_ep(epb); | 772 | ep = sctp_ep(epb); |
796 | if (sctp_endpoint_is_match(ep, net, laddr)) | 773 | if (sctp_endpoint_is_match(ep, laddr)) |
797 | goto hit; | 774 | goto hit; |
798 | } | 775 | } |
799 | 776 | ||
800 | ep = sctp_sk(net->sctp.ctl_sock)->ep; | 777 | ep = sctp_sk((sctp_get_ctl_sock()))->ep; |
801 | 778 | ||
802 | hit: | 779 | hit: |
803 | sctp_endpoint_hold(ep); | 780 | sctp_endpoint_hold(ep); |
@@ -808,15 +785,13 @@ hit: | |||
808 | /* Insert association into the hash table. */ | 785 | /* Insert association into the hash table. */ |
809 | static void __sctp_hash_established(struct sctp_association *asoc) | 786 | static void __sctp_hash_established(struct sctp_association *asoc) |
810 | { | 787 | { |
811 | struct net *net = sock_net(asoc->base.sk); | ||
812 | struct sctp_ep_common *epb; | 788 | struct sctp_ep_common *epb; |
813 | struct sctp_hashbucket *head; | 789 | struct sctp_hashbucket *head; |
814 | 790 | ||
815 | epb = &asoc->base; | 791 | epb = &asoc->base; |
816 | 792 | ||
817 | /* Calculate which chain this entry will belong to. */ | 793 | /* Calculate which chain this entry will belong to. */ |
818 | epb->hashent = sctp_assoc_hashfn(net, epb->bind_addr.port, | 794 | epb->hashent = sctp_assoc_hashfn(epb->bind_addr.port, asoc->peer.port); |
819 | asoc->peer.port); | ||
820 | 795 | ||
821 | head = &sctp_assoc_hashtable[epb->hashent]; | 796 | head = &sctp_assoc_hashtable[epb->hashent]; |
822 | 797 | ||
@@ -839,19 +814,18 @@ void sctp_hash_established(struct sctp_association *asoc) | |||
839 | /* Remove association from the hash table. */ | 814 | /* Remove association from the hash table. */ |
840 | static void __sctp_unhash_established(struct sctp_association *asoc) | 815 | static void __sctp_unhash_established(struct sctp_association *asoc) |
841 | { | 816 | { |
842 | struct net *net = sock_net(asoc->base.sk); | ||
843 | struct sctp_hashbucket *head; | 817 | struct sctp_hashbucket *head; |
844 | struct sctp_ep_common *epb; | 818 | struct sctp_ep_common *epb; |
845 | 819 | ||
846 | epb = &asoc->base; | 820 | epb = &asoc->base; |
847 | 821 | ||
848 | epb->hashent = sctp_assoc_hashfn(net, epb->bind_addr.port, | 822 | epb->hashent = sctp_assoc_hashfn(epb->bind_addr.port, |
849 | asoc->peer.port); | 823 | asoc->peer.port); |
850 | 824 | ||
851 | head = &sctp_assoc_hashtable[epb->hashent]; | 825 | head = &sctp_assoc_hashtable[epb->hashent]; |
852 | 826 | ||
853 | sctp_write_lock(&head->lock); | 827 | sctp_write_lock(&head->lock); |
854 | hlist_del_init(&epb->node); | 828 | __hlist_del(&epb->node); |
855 | sctp_write_unlock(&head->lock); | 829 | sctp_write_unlock(&head->lock); |
856 | } | 830 | } |
857 | 831 | ||
@@ -868,7 +842,6 @@ void sctp_unhash_established(struct sctp_association *asoc) | |||
868 | 842 | ||
869 | /* Look up an association. */ | 843 | /* Look up an association. */ |
870 | static struct sctp_association *__sctp_lookup_association( | 844 | static struct sctp_association *__sctp_lookup_association( |
871 | struct net *net, | ||
872 | const union sctp_addr *local, | 845 | const union sctp_addr *local, |
873 | const union sctp_addr *peer, | 846 | const union sctp_addr *peer, |
874 | struct sctp_transport **pt) | 847 | struct sctp_transport **pt) |
@@ -883,13 +856,12 @@ static struct sctp_association *__sctp_lookup_association( | |||
883 | /* Optimize here for direct hit, only listening connections can | 856 | /* Optimize here for direct hit, only listening connections can |
884 | * have wildcards anyways. | 857 | * have wildcards anyways. |
885 | */ | 858 | */ |
886 | hash = sctp_assoc_hashfn(net, ntohs(local->v4.sin_port), | 859 | hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port)); |
887 | ntohs(peer->v4.sin_port)); | ||
888 | head = &sctp_assoc_hashtable[hash]; | 860 | head = &sctp_assoc_hashtable[hash]; |
889 | read_lock(&head->lock); | 861 | read_lock(&head->lock); |
890 | sctp_for_each_hentry(epb, node, &head->chain) { | 862 | sctp_for_each_hentry(epb, node, &head->chain) { |
891 | asoc = sctp_assoc(epb); | 863 | asoc = sctp_assoc(epb); |
892 | transport = sctp_assoc_is_match(asoc, net, local, peer); | 864 | transport = sctp_assoc_is_match(asoc, local, peer); |
893 | if (transport) | 865 | if (transport) |
894 | goto hit; | 866 | goto hit; |
895 | } | 867 | } |
@@ -907,29 +879,27 @@ hit: | |||
907 | 879 | ||
908 | /* Look up an association. BH-safe. */ | 880 | /* Look up an association. BH-safe. */ |
909 | SCTP_STATIC | 881 | SCTP_STATIC |
910 | struct sctp_association *sctp_lookup_association(struct net *net, | 882 | struct sctp_association *sctp_lookup_association(const union sctp_addr *laddr, |
911 | const union sctp_addr *laddr, | ||
912 | const union sctp_addr *paddr, | 883 | const union sctp_addr *paddr, |
913 | struct sctp_transport **transportp) | 884 | struct sctp_transport **transportp) |
914 | { | 885 | { |
915 | struct sctp_association *asoc; | 886 | struct sctp_association *asoc; |
916 | 887 | ||
917 | sctp_local_bh_disable(); | 888 | sctp_local_bh_disable(); |
918 | asoc = __sctp_lookup_association(net, laddr, paddr, transportp); | 889 | asoc = __sctp_lookup_association(laddr, paddr, transportp); |
919 | sctp_local_bh_enable(); | 890 | sctp_local_bh_enable(); |
920 | 891 | ||
921 | return asoc; | 892 | return asoc; |
922 | } | 893 | } |
923 | 894 | ||
924 | /* Is there an association matching the given local and peer addresses? */ | 895 | /* Is there an association matching the given local and peer addresses? */ |
925 | int sctp_has_association(struct net *net, | 896 | int sctp_has_association(const union sctp_addr *laddr, |
926 | const union sctp_addr *laddr, | ||
927 | const union sctp_addr *paddr) | 897 | const union sctp_addr *paddr) |
928 | { | 898 | { |
929 | struct sctp_association *asoc; | 899 | struct sctp_association *asoc; |
930 | struct sctp_transport *transport; | 900 | struct sctp_transport *transport; |
931 | 901 | ||
932 | if ((asoc = sctp_lookup_association(net, laddr, paddr, &transport))) { | 902 | if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) { |
933 | sctp_association_put(asoc); | 903 | sctp_association_put(asoc); |
934 | return 1; | 904 | return 1; |
935 | } | 905 | } |
@@ -955,8 +925,7 @@ int sctp_has_association(struct net *net, | |||
955 | * in certain circumstances. | 925 | * in certain circumstances. |
956 | * | 926 | * |
957 | */ | 927 | */ |
958 | static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, | 928 | static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb, |
959 | struct sk_buff *skb, | ||
960 | const union sctp_addr *laddr, struct sctp_transport **transportp) | 929 | const union sctp_addr *laddr, struct sctp_transport **transportp) |
961 | { | 930 | { |
962 | struct sctp_association *asoc; | 931 | struct sctp_association *asoc; |
@@ -996,7 +965,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, | |||
996 | 965 | ||
997 | af->from_addr_param(paddr, params.addr, sh->source, 0); | 966 | af->from_addr_param(paddr, params.addr, sh->source, 0); |
998 | 967 | ||
999 | asoc = __sctp_lookup_association(net, laddr, paddr, &transport); | 968 | asoc = __sctp_lookup_association(laddr, paddr, &transport); |
1000 | if (asoc) | 969 | if (asoc) |
1001 | return asoc; | 970 | return asoc; |
1002 | } | 971 | } |
@@ -1019,7 +988,6 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, | |||
1019 | * subsequent ASCONF Chunks. If found, proceed to rule D4. | 988 | * subsequent ASCONF Chunks. If found, proceed to rule D4. |
1020 | */ | 989 | */ |
1021 | static struct sctp_association *__sctp_rcv_asconf_lookup( | 990 | static struct sctp_association *__sctp_rcv_asconf_lookup( |
1022 | struct net *net, | ||
1023 | sctp_chunkhdr_t *ch, | 991 | sctp_chunkhdr_t *ch, |
1024 | const union sctp_addr *laddr, | 992 | const union sctp_addr *laddr, |
1025 | __be16 peer_port, | 993 | __be16 peer_port, |
@@ -1039,7 +1007,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( | |||
1039 | 1007 | ||
1040 | af->from_addr_param(&paddr, param, peer_port, 0); | 1008 | af->from_addr_param(&paddr, param, peer_port, 0); |
1041 | 1009 | ||
1042 | return __sctp_lookup_association(net, laddr, &paddr, transportp); | 1010 | return __sctp_lookup_association(laddr, &paddr, transportp); |
1043 | } | 1011 | } |
1044 | 1012 | ||
1045 | 1013 | ||
@@ -1052,8 +1020,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( | |||
1052 | * This means that any chunks that can help us identify the association need | 1020 | * This means that any chunks that can help us identify the association need |
1053 | * to be looked at to find this association. | 1021 | * to be looked at to find this association. |
1054 | */ | 1022 | */ |
1055 | static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, | 1023 | static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb, |
1056 | struct sk_buff *skb, | ||
1057 | const union sctp_addr *laddr, | 1024 | const union sctp_addr *laddr, |
1058 | struct sctp_transport **transportp) | 1025 | struct sctp_transport **transportp) |
1059 | { | 1026 | { |
@@ -1094,9 +1061,8 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, | |||
1094 | break; | 1061 | break; |
1095 | 1062 | ||
1096 | case SCTP_CID_ASCONF: | 1063 | case SCTP_CID_ASCONF: |
1097 | if (have_auth || net->sctp.addip_noauth) | 1064 | if (have_auth || sctp_addip_noauth) |
1098 | asoc = __sctp_rcv_asconf_lookup( | 1065 | asoc = __sctp_rcv_asconf_lookup(ch, laddr, |
1099 | net, ch, laddr, | ||
1100 | sctp_hdr(skb)->source, | 1066 | sctp_hdr(skb)->source, |
1101 | transportp); | 1067 | transportp); |
1102 | default: | 1068 | default: |
@@ -1119,8 +1085,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, | |||
1119 | * include looking inside of INIT/INIT-ACK chunks or after the AUTH | 1085 | * include looking inside of INIT/INIT-ACK chunks or after the AUTH |
1120 | * chunks. | 1086 | * chunks. |
1121 | */ | 1087 | */ |
1122 | static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, | 1088 | static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb, |
1123 | struct sk_buff *skb, | ||
1124 | const union sctp_addr *laddr, | 1089 | const union sctp_addr *laddr, |
1125 | struct sctp_transport **transportp) | 1090 | struct sctp_transport **transportp) |
1126 | { | 1091 | { |
@@ -1140,11 +1105,11 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, | |||
1140 | switch (ch->type) { | 1105 | switch (ch->type) { |
1141 | case SCTP_CID_INIT: | 1106 | case SCTP_CID_INIT: |
1142 | case SCTP_CID_INIT_ACK: | 1107 | case SCTP_CID_INIT_ACK: |
1143 | return __sctp_rcv_init_lookup(net, skb, laddr, transportp); | 1108 | return __sctp_rcv_init_lookup(skb, laddr, transportp); |
1144 | break; | 1109 | break; |
1145 | 1110 | ||
1146 | default: | 1111 | default: |
1147 | return __sctp_rcv_walk_lookup(net, skb, laddr, transportp); | 1112 | return __sctp_rcv_walk_lookup(skb, laddr, transportp); |
1148 | break; | 1113 | break; |
1149 | } | 1114 | } |
1150 | 1115 | ||
@@ -1153,22 +1118,21 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, | |||
1153 | } | 1118 | } |
1154 | 1119 | ||
1155 | /* Lookup an association for an inbound skb. */ | 1120 | /* Lookup an association for an inbound skb. */ |
1156 | static struct sctp_association *__sctp_rcv_lookup(struct net *net, | 1121 | static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, |
1157 | struct sk_buff *skb, | ||
1158 | const union sctp_addr *paddr, | 1122 | const union sctp_addr *paddr, |
1159 | const union sctp_addr *laddr, | 1123 | const union sctp_addr *laddr, |
1160 | struct sctp_transport **transportp) | 1124 | struct sctp_transport **transportp) |
1161 | { | 1125 | { |
1162 | struct sctp_association *asoc; | 1126 | struct sctp_association *asoc; |
1163 | 1127 | ||
1164 | asoc = __sctp_lookup_association(net, laddr, paddr, transportp); | 1128 | asoc = __sctp_lookup_association(laddr, paddr, transportp); |
1165 | 1129 | ||
1166 | /* Further lookup for INIT/INIT-ACK packets. | 1130 | /* Further lookup for INIT/INIT-ACK packets. |
1167 | * SCTP Implementors Guide, 2.18 Handling of address | 1131 | * SCTP Implementors Guide, 2.18 Handling of address |
1168 | * parameters within the INIT or INIT-ACK. | 1132 | * parameters within the INIT or INIT-ACK. |
1169 | */ | 1133 | */ |
1170 | if (!asoc) | 1134 | if (!asoc) |
1171 | asoc = __sctp_rcv_lookup_harder(net, skb, laddr, transportp); | 1135 | asoc = __sctp_rcv_lookup_harder(skb, laddr, transportp); |
1172 | 1136 | ||
1173 | return asoc; | 1137 | return asoc; |
1174 | } | 1138 | } |