aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/endpointola.c6
-rw-r--r--net/sctp/input.c64
-rw-r--r--net/sctp/ipv6.c3
4 files changed, 49 insertions, 28 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ebaef3ed606..a3601f35ac1 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1089,13 +1089,15 @@ out:
1089 1089
1090/* Is this the association we are looking for? */ 1090/* Is this the association we are looking for? */
1091struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc, 1091struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
1092 struct net *net,
1092 const union sctp_addr *laddr, 1093 const union sctp_addr *laddr,
1093 const union sctp_addr *paddr) 1094 const union sctp_addr *paddr)
1094{ 1095{
1095 struct sctp_transport *transport; 1096 struct sctp_transport *transport;
1096 1097
1097 if ((htons(asoc->base.bind_addr.port) == laddr->v4.sin_port) && 1098 if ((htons(asoc->base.bind_addr.port) == laddr->v4.sin_port) &&
1098 (htons(asoc->peer.port) == paddr->v4.sin_port)) { 1099 (htons(asoc->peer.port) == paddr->v4.sin_port) &&
1100 net_eq(sock_net(asoc->base.sk), net)) {
1099 transport = sctp_assoc_lookup_paddr(asoc, paddr); 1101 transport = sctp_assoc_lookup_paddr(asoc, paddr);
1100 if (!transport) 1102 if (!transport)
1101 goto out; 1103 goto out;
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 50c87b4ad76..6b763939345 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -345,7 +345,8 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
345 345
346 rport = ntohs(paddr->v4.sin_port); 346 rport = ntohs(paddr->v4.sin_port);
347 347
348 hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); 348 hash = sctp_assoc_hashfn(sock_net(ep->base.sk), ep->base.bind_addr.port,
349 rport);
349 head = &sctp_assoc_hashtable[hash]; 350 head = &sctp_assoc_hashtable[hash];
350 read_lock(&head->lock); 351 read_lock(&head->lock);
351 sctp_for_each_hentry(epb, node, &head->chain) { 352 sctp_for_each_hentry(epb, node, &head->chain) {
@@ -388,13 +389,14 @@ int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
388{ 389{
389 struct sctp_sockaddr_entry *addr; 390 struct sctp_sockaddr_entry *addr;
390 struct sctp_bind_addr *bp; 391 struct sctp_bind_addr *bp;
392 struct net *net = sock_net(ep->base.sk);
391 393
392 bp = &ep->base.bind_addr; 394 bp = &ep->base.bind_addr;
393 /* This function is called with the socket lock held, 395 /* This function is called with the socket lock held,
394 * so the address_list can not change. 396 * so the address_list can not change.
395 */ 397 */
396 list_for_each_entry(addr, &bp->address_list, list) { 398 list_for_each_entry(addr, &bp->address_list, list) {
397 if (sctp_has_association(&addr->a, paddr)) 399 if (sctp_has_association(net, &addr->a, paddr))
398 return 1; 400 return 1;
399 } 401 }
400 402
diff --git a/net/sctp/input.c b/net/sctp/input.c
index c0ca893ab1d..a7e9a85b5ac 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -66,13 +66,15 @@
66 66
67/* Forward declarations for internal helpers. */ 67/* Forward declarations for internal helpers. */
68static int sctp_rcv_ootb(struct sk_buff *); 68static int sctp_rcv_ootb(struct sk_buff *);
69static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, 69static struct sctp_association *__sctp_rcv_lookup(struct net *net,
70 struct sk_buff *skb,
70 const union sctp_addr *laddr, 71 const union sctp_addr *laddr,
71 const union sctp_addr *paddr, 72 const union sctp_addr *paddr,
72 struct sctp_transport **transportp); 73 struct sctp_transport **transportp);
73static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, 74static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
74 const union sctp_addr *laddr); 75 const union sctp_addr *laddr);
75static struct sctp_association *__sctp_lookup_association( 76static struct sctp_association *__sctp_lookup_association(
77 struct net *net,
76 const union sctp_addr *local, 78 const union sctp_addr *local,
77 const union sctp_addr *peer, 79 const union sctp_addr *peer,
78 struct sctp_transport **pt); 80 struct sctp_transport **pt);
@@ -180,7 +182,7 @@ int sctp_rcv(struct sk_buff *skb)
180 !af->addr_valid(&dest, NULL, skb)) 182 !af->addr_valid(&dest, NULL, skb))
181 goto discard_it; 183 goto discard_it;
182 184
183 asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); 185 asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport);
184 186
185 if (!asoc) 187 if (!asoc)
186 ep = __sctp_rcv_lookup_endpoint(net, &dest); 188 ep = __sctp_rcv_lookup_endpoint(net, &dest);
@@ -476,7 +478,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
476} 478}
477 479
478/* Common lookup code for icmp/icmpv6 error handler. */ 480/* Common lookup code for icmp/icmpv6 error handler. */
479struct sock *sctp_err_lookup(int family, struct sk_buff *skb, 481struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb,
480 struct sctphdr *sctphdr, 482 struct sctphdr *sctphdr,
481 struct sctp_association **app, 483 struct sctp_association **app,
482 struct sctp_transport **tpp) 484 struct sctp_transport **tpp)
@@ -505,7 +507,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
505 /* Look for an association that matches the incoming ICMP error 507 /* Look for an association that matches the incoming ICMP error
506 * packet. 508 * packet.
507 */ 509 */
508 asoc = __sctp_lookup_association(&saddr, &daddr, &transport); 510 asoc = __sctp_lookup_association(net, &saddr, &daddr, &transport);
509 if (!asoc) 511 if (!asoc)
510 return NULL; 512 return NULL;
511 513
@@ -588,6 +590,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
588 struct inet_sock *inet; 590 struct inet_sock *inet;
589 sk_buff_data_t saveip, savesctp; 591 sk_buff_data_t saveip, savesctp;
590 int err; 592 int err;
593 struct net *net = dev_net(skb->dev);
591 594
592 if (skb->len < ihlen + 8) { 595 if (skb->len < ihlen + 8) {
593 ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS); 596 ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
@@ -599,7 +602,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
599 savesctp = skb->transport_header; 602 savesctp = skb->transport_header;
600 skb_reset_network_header(skb); 603 skb_reset_network_header(skb);
601 skb_set_transport_header(skb, ihlen); 604 skb_set_transport_header(skb, ihlen);
602 sk = sctp_err_lookup(AF_INET, skb, sctp_hdr(skb), &asoc, &transport); 605 sk = sctp_err_lookup(net, AF_INET, skb, sctp_hdr(skb), &asoc, &transport);
603 /* Put back, the original values. */ 606 /* Put back, the original values. */
604 skb->network_header = saveip; 607 skb->network_header = saveip;
605 skb->transport_header = savesctp; 608 skb->transport_header = savesctp;
@@ -803,13 +806,15 @@ hit:
803/* Insert association into the hash table. */ 806/* Insert association into the hash table. */
804static void __sctp_hash_established(struct sctp_association *asoc) 807static void __sctp_hash_established(struct sctp_association *asoc)
805{ 808{
809 struct net *net = sock_net(asoc->base.sk);
806 struct sctp_ep_common *epb; 810 struct sctp_ep_common *epb;
807 struct sctp_hashbucket *head; 811 struct sctp_hashbucket *head;
808 812
809 epb = &asoc->base; 813 epb = &asoc->base;
810 814
811 /* Calculate which chain this entry will belong to. */ 815 /* Calculate which chain this entry will belong to. */
812 epb->hashent = sctp_assoc_hashfn(epb->bind_addr.port, asoc->peer.port); 816 epb->hashent = sctp_assoc_hashfn(net, epb->bind_addr.port,
817 asoc->peer.port);
813 818
814 head = &sctp_assoc_hashtable[epb->hashent]; 819 head = &sctp_assoc_hashtable[epb->hashent];
815 820
@@ -832,12 +837,13 @@ void sctp_hash_established(struct sctp_association *asoc)
832/* Remove association from the hash table. */ 837/* Remove association from the hash table. */
833static void __sctp_unhash_established(struct sctp_association *asoc) 838static void __sctp_unhash_established(struct sctp_association *asoc)
834{ 839{
840 struct net *net = sock_net(asoc->base.sk);
835 struct sctp_hashbucket *head; 841 struct sctp_hashbucket *head;
836 struct sctp_ep_common *epb; 842 struct sctp_ep_common *epb;
837 843
838 epb = &asoc->base; 844 epb = &asoc->base;
839 845
840 epb->hashent = sctp_assoc_hashfn(epb->bind_addr.port, 846 epb->hashent = sctp_assoc_hashfn(net, epb->bind_addr.port,
841 asoc->peer.port); 847 asoc->peer.port);
842 848
843 head = &sctp_assoc_hashtable[epb->hashent]; 849 head = &sctp_assoc_hashtable[epb->hashent];
@@ -860,6 +866,7 @@ void sctp_unhash_established(struct sctp_association *asoc)
860 866
861/* Look up an association. */ 867/* Look up an association. */
862static struct sctp_association *__sctp_lookup_association( 868static struct sctp_association *__sctp_lookup_association(
869 struct net *net,
863 const union sctp_addr *local, 870 const union sctp_addr *local,
864 const union sctp_addr *peer, 871 const union sctp_addr *peer,
865 struct sctp_transport **pt) 872 struct sctp_transport **pt)
@@ -874,12 +881,13 @@ static struct sctp_association *__sctp_lookup_association(
874 /* Optimize here for direct hit, only listening connections can 881 /* Optimize here for direct hit, only listening connections can
875 * have wildcards anyways. 882 * have wildcards anyways.
876 */ 883 */
877 hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port)); 884 hash = sctp_assoc_hashfn(net, ntohs(local->v4.sin_port),
885 ntohs(peer->v4.sin_port));
878 head = &sctp_assoc_hashtable[hash]; 886 head = &sctp_assoc_hashtable[hash];
879 read_lock(&head->lock); 887 read_lock(&head->lock);
880 sctp_for_each_hentry(epb, node, &head->chain) { 888 sctp_for_each_hentry(epb, node, &head->chain) {
881 asoc = sctp_assoc(epb); 889 asoc = sctp_assoc(epb);
882 transport = sctp_assoc_is_match(asoc, local, peer); 890 transport = sctp_assoc_is_match(asoc, net, local, peer);
883 if (transport) 891 if (transport)
884 goto hit; 892 goto hit;
885 } 893 }
@@ -897,27 +905,29 @@ hit:
897 905
898/* Look up an association. BH-safe. */ 906/* Look up an association. BH-safe. */
899SCTP_STATIC 907SCTP_STATIC
900struct sctp_association *sctp_lookup_association(const union sctp_addr *laddr, 908struct sctp_association *sctp_lookup_association(struct net *net,
909 const union sctp_addr *laddr,
901 const union sctp_addr *paddr, 910 const union sctp_addr *paddr,
902 struct sctp_transport **transportp) 911 struct sctp_transport **transportp)
903{ 912{
904 struct sctp_association *asoc; 913 struct sctp_association *asoc;
905 914
906 sctp_local_bh_disable(); 915 sctp_local_bh_disable();
907 asoc = __sctp_lookup_association(laddr, paddr, transportp); 916 asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
908 sctp_local_bh_enable(); 917 sctp_local_bh_enable();
909 918
910 return asoc; 919 return asoc;
911} 920}
912 921
913/* Is there an association matching the given local and peer addresses? */ 922/* Is there an association matching the given local and peer addresses? */
914int sctp_has_association(const union sctp_addr *laddr, 923int sctp_has_association(struct net *net,
924 const union sctp_addr *laddr,
915 const union sctp_addr *paddr) 925 const union sctp_addr *paddr)
916{ 926{
917 struct sctp_association *asoc; 927 struct sctp_association *asoc;
918 struct sctp_transport *transport; 928 struct sctp_transport *transport;
919 929
920 if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) { 930 if ((asoc = sctp_lookup_association(net, laddr, paddr, &transport))) {
921 sctp_association_put(asoc); 931 sctp_association_put(asoc);
922 return 1; 932 return 1;
923 } 933 }
@@ -943,7 +953,8 @@ int sctp_has_association(const union sctp_addr *laddr,
943 * in certain circumstances. 953 * in certain circumstances.
944 * 954 *
945 */ 955 */
946static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb, 956static struct sctp_association *__sctp_rcv_init_lookup(struct net *net,
957 struct sk_buff *skb,
947 const union sctp_addr *laddr, struct sctp_transport **transportp) 958 const union sctp_addr *laddr, struct sctp_transport **transportp)
948{ 959{
949 struct sctp_association *asoc; 960 struct sctp_association *asoc;
@@ -983,7 +994,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
983 994
984 af->from_addr_param(paddr, params.addr, sh->source, 0); 995 af->from_addr_param(paddr, params.addr, sh->source, 0);
985 996
986 asoc = __sctp_lookup_association(laddr, paddr, &transport); 997 asoc = __sctp_lookup_association(net, laddr, paddr, &transport);
987 if (asoc) 998 if (asoc)
988 return asoc; 999 return asoc;
989 } 1000 }
@@ -1006,6 +1017,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
1006 * subsequent ASCONF Chunks. If found, proceed to rule D4. 1017 * subsequent ASCONF Chunks. If found, proceed to rule D4.
1007 */ 1018 */
1008static struct sctp_association *__sctp_rcv_asconf_lookup( 1019static struct sctp_association *__sctp_rcv_asconf_lookup(
1020 struct net *net,
1009 sctp_chunkhdr_t *ch, 1021 sctp_chunkhdr_t *ch,
1010 const union sctp_addr *laddr, 1022 const union sctp_addr *laddr,
1011 __be16 peer_port, 1023 __be16 peer_port,
@@ -1025,7 +1037,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
1025 1037
1026 af->from_addr_param(&paddr, param, peer_port, 0); 1038 af->from_addr_param(&paddr, param, peer_port, 0);
1027 1039
1028 return __sctp_lookup_association(laddr, &paddr, transportp); 1040 return __sctp_lookup_association(net, laddr, &paddr, transportp);
1029} 1041}
1030 1042
1031 1043
@@ -1038,7 +1050,8 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
1038* This means that any chunks that can help us identify the association need 1050* This means that any chunks that can help us identify the association need
1039* to be looked at to find this association. 1051* to be looked at to find this association.
1040*/ 1052*/
1041static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb, 1053static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net,
1054 struct sk_buff *skb,
1042 const union sctp_addr *laddr, 1055 const union sctp_addr *laddr,
1043 struct sctp_transport **transportp) 1056 struct sctp_transport **transportp)
1044{ 1057{
@@ -1080,7 +1093,8 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb,
1080 1093
1081 case SCTP_CID_ASCONF: 1094 case SCTP_CID_ASCONF:
1082 if (have_auth || sctp_addip_noauth) 1095 if (have_auth || sctp_addip_noauth)
1083 asoc = __sctp_rcv_asconf_lookup(ch, laddr, 1096 asoc = __sctp_rcv_asconf_lookup(
1097 net, ch, laddr,
1084 sctp_hdr(skb)->source, 1098 sctp_hdr(skb)->source,
1085 transportp); 1099 transportp);
1086 default: 1100 default:
@@ -1103,7 +1117,8 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb,
1103 * include looking inside of INIT/INIT-ACK chunks or after the AUTH 1117 * include looking inside of INIT/INIT-ACK chunks or after the AUTH
1104 * chunks. 1118 * chunks.
1105 */ 1119 */
1106static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb, 1120static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net,
1121 struct sk_buff *skb,
1107 const union sctp_addr *laddr, 1122 const union sctp_addr *laddr,
1108 struct sctp_transport **transportp) 1123 struct sctp_transport **transportp)
1109{ 1124{
@@ -1123,11 +1138,11 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
1123 switch (ch->type) { 1138 switch (ch->type) {
1124 case SCTP_CID_INIT: 1139 case SCTP_CID_INIT:
1125 case SCTP_CID_INIT_ACK: 1140 case SCTP_CID_INIT_ACK:
1126 return __sctp_rcv_init_lookup(skb, laddr, transportp); 1141 return __sctp_rcv_init_lookup(net, skb, laddr, transportp);
1127 break; 1142 break;
1128 1143
1129 default: 1144 default:
1130 return __sctp_rcv_walk_lookup(skb, laddr, transportp); 1145 return __sctp_rcv_walk_lookup(net, skb, laddr, transportp);
1131 break; 1146 break;
1132 } 1147 }
1133 1148
@@ -1136,21 +1151,22 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
1136} 1151}
1137 1152
1138/* Lookup an association for an inbound skb. */ 1153/* Lookup an association for an inbound skb. */
1139static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, 1154static struct sctp_association *__sctp_rcv_lookup(struct net *net,
1155 struct sk_buff *skb,
1140 const union sctp_addr *paddr, 1156 const union sctp_addr *paddr,
1141 const union sctp_addr *laddr, 1157 const union sctp_addr *laddr,
1142 struct sctp_transport **transportp) 1158 struct sctp_transport **transportp)
1143{ 1159{
1144 struct sctp_association *asoc; 1160 struct sctp_association *asoc;
1145 1161
1146 asoc = __sctp_lookup_association(laddr, paddr, transportp); 1162 asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
1147 1163
1148 /* Further lookup for INIT/INIT-ACK packets. 1164 /* Further lookup for INIT/INIT-ACK packets.
1149 * SCTP Implementors Guide, 2.18 Handling of address 1165 * SCTP Implementors Guide, 2.18 Handling of address
1150 * parameters within the INIT or INIT-ACK. 1166 * parameters within the INIT or INIT-ACK.
1151 */ 1167 */
1152 if (!asoc) 1168 if (!asoc)
1153 asoc = __sctp_rcv_lookup_harder(skb, laddr, transportp); 1169 asoc = __sctp_rcv_lookup_harder(net, skb, laddr, transportp);
1154 1170
1155 return asoc; 1171 return asoc;
1156} 1172}
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ed7139ea797..2165a7ed25f 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -154,6 +154,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
154 struct ipv6_pinfo *np; 154 struct ipv6_pinfo *np;
155 sk_buff_data_t saveip, savesctp; 155 sk_buff_data_t saveip, savesctp;
156 int err; 156 int err;
157 struct net *net = dev_net(skb->dev);
157 158
158 idev = in6_dev_get(skb->dev); 159 idev = in6_dev_get(skb->dev);
159 160
@@ -162,7 +163,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
162 savesctp = skb->transport_header; 163 savesctp = skb->transport_header;
163 skb_reset_network_header(skb); 164 skb_reset_network_header(skb);
164 skb_set_transport_header(skb, offset); 165 skb_set_transport_header(skb, offset);
165 sk = sctp_err_lookup(AF_INET6, skb, sctp_hdr(skb), &asoc, &transport); 166 sk = sctp_err_lookup(net, AF_INET6, skb, sctp_hdr(skb), &asoc, &transport);
166 /* Put back, the original pointers. */ 167 /* Put back, the original pointers. */
167 skb->network_header = saveip; 168 skb->network_header = saveip;
168 skb->transport_header = savesctp; 169 skb->transport_header = savesctp;