diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-12-03 02:09:38 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-12-03 02:09:38 -0500 |
| commit | b3c6aeb3ce26b286769d2deafec47d218c83dd09 (patch) | |
| tree | 06378a021f5873003a07f0388aa0cb6e81a32c19 /net | |
| parent | af2eb17bac41a116b73d85b3fb160405c32bea5b (diff) | |
| parent | af1afe866297448ad8a1da99fa8a6af86c43c909 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/af_inet.c | 7 | ||||
| -rw-r--r-- | net/ipv4/igmp.c | 5 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 47 | ||||
| -rw-r--r-- | net/ipv6/mcast.c | 5 | ||||
| -rw-r--r-- | net/sctp/socket.c | 10 | ||||
| -rw-r--r-- | net/sctp/transport.c | 3 |
6 files changed, 52 insertions, 25 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index eaa150c33b04..d368cf249000 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -228,13 +228,14 @@ static int inet_create(struct socket *sock, int protocol) | |||
| 228 | unsigned char answer_flags; | 228 | unsigned char answer_flags; |
| 229 | char answer_no_check; | 229 | char answer_no_check; |
| 230 | int try_loading_module = 0; | 230 | int try_loading_module = 0; |
| 231 | int err = -ESOCKTNOSUPPORT; | 231 | int err; |
| 232 | 232 | ||
| 233 | sock->state = SS_UNCONNECTED; | 233 | sock->state = SS_UNCONNECTED; |
| 234 | 234 | ||
| 235 | /* Look for the requested type/protocol pair. */ | 235 | /* Look for the requested type/protocol pair. */ |
| 236 | answer = NULL; | 236 | answer = NULL; |
| 237 | lookup_protocol: | 237 | lookup_protocol: |
| 238 | err = -ESOCKTNOSUPPORT; | ||
| 238 | rcu_read_lock(); | 239 | rcu_read_lock(); |
| 239 | list_for_each_rcu(p, &inetsw[sock->type]) { | 240 | list_for_each_rcu(p, &inetsw[sock->type]) { |
| 240 | answer = list_entry(p, struct inet_protosw, list); | 241 | answer = list_entry(p, struct inet_protosw, list); |
| @@ -252,6 +253,7 @@ lookup_protocol: | |||
| 252 | if (IPPROTO_IP == answer->protocol) | 253 | if (IPPROTO_IP == answer->protocol) |
| 253 | break; | 254 | break; |
| 254 | } | 255 | } |
| 256 | err = -EPROTONOSUPPORT; | ||
| 255 | answer = NULL; | 257 | answer = NULL; |
| 256 | } | 258 | } |
| 257 | 259 | ||
| @@ -280,9 +282,6 @@ lookup_protocol: | |||
| 280 | err = -EPERM; | 282 | err = -EPERM; |
| 281 | if (answer->capability > 0 && !capable(answer->capability)) | 283 | if (answer->capability > 0 && !capable(answer->capability)) |
| 282 | goto out_rcu_unlock; | 284 | goto out_rcu_unlock; |
| 283 | err = -EPROTONOSUPPORT; | ||
| 284 | if (!protocol) | ||
| 285 | goto out_rcu_unlock; | ||
| 286 | 285 | ||
| 287 | sock->ops = answer->ops; | 286 | sock->ops = answer->ops; |
| 288 | answer_prot = answer->prot; | 287 | answer_prot = answer->prot; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index c04607b49212..4a195c724f01 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -897,7 +897,10 @@ int igmp_rcv(struct sk_buff *skb) | |||
| 897 | /* Is it our report looped back? */ | 897 | /* Is it our report looped back? */ |
| 898 | if (((struct rtable*)skb->dst)->fl.iif == 0) | 898 | if (((struct rtable*)skb->dst)->fl.iif == 0) |
| 899 | break; | 899 | break; |
| 900 | igmp_heard_report(in_dev, ih->group); | 900 | /* don't rely on MC router hearing unicast reports */ |
| 901 | if (skb->pkt_type == PACKET_MULTICAST || | ||
| 902 | skb->pkt_type == PACKET_BROADCAST) | ||
| 903 | igmp_heard_report(in_dev, ih->group); | ||
| 901 | break; | 904 | break; |
| 902 | case IGMP_PIM: | 905 | case IGMP_PIM: |
| 903 | #ifdef CONFIG_IP_PIMSM_V1 | 906 | #ifdef CONFIG_IP_PIMSM_V1 |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c63b8ce0e1b5..d9546380fa04 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -92,10 +92,13 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 92 | struct proto *answer_prot; | 92 | struct proto *answer_prot; |
| 93 | unsigned char answer_flags; | 93 | unsigned char answer_flags; |
| 94 | char answer_no_check; | 94 | char answer_no_check; |
| 95 | int rc; | 95 | int try_loading_module = 0; |
| 96 | int err; | ||
| 96 | 97 | ||
| 97 | /* Look for the requested type/protocol pair. */ | 98 | /* Look for the requested type/protocol pair. */ |
| 98 | answer = NULL; | 99 | answer = NULL; |
| 100 | lookup_protocol: | ||
| 101 | err = -ESOCKTNOSUPPORT; | ||
| 99 | rcu_read_lock(); | 102 | rcu_read_lock(); |
| 100 | list_for_each_rcu(p, &inetsw6[sock->type]) { | 103 | list_for_each_rcu(p, &inetsw6[sock->type]) { |
| 101 | answer = list_entry(p, struct inet_protosw, list); | 104 | answer = list_entry(p, struct inet_protosw, list); |
| @@ -113,21 +116,37 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 113 | if (IPPROTO_IP == answer->protocol) | 116 | if (IPPROTO_IP == answer->protocol) |
| 114 | break; | 117 | break; |
| 115 | } | 118 | } |
| 119 | err = -EPROTONOSUPPORT; | ||
| 116 | answer = NULL; | 120 | answer = NULL; |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 119 | rc = -ESOCKTNOSUPPORT; | 123 | if (!answer) { |
| 120 | if (!answer) | 124 | if (try_loading_module < 2) { |
| 121 | goto out_rcu_unlock; | 125 | rcu_read_unlock(); |
| 122 | rc = -EPERM; | 126 | /* |
| 127 | * Be more specific, e.g. net-pf-10-proto-132-type-1 | ||
| 128 | * (net-pf-PF_INET6-proto-IPPROTO_SCTP-type-SOCK_STREAM) | ||
| 129 | */ | ||
| 130 | if (++try_loading_module == 1) | ||
| 131 | request_module("net-pf-%d-proto-%d-type-%d", | ||
| 132 | PF_INET6, protocol, sock->type); | ||
| 133 | /* | ||
| 134 | * Fall back to generic, e.g. net-pf-10-proto-132 | ||
| 135 | * (net-pf-PF_INET6-proto-IPPROTO_SCTP) | ||
| 136 | */ | ||
| 137 | else | ||
| 138 | request_module("net-pf-%d-proto-%d", | ||
| 139 | PF_INET6, protocol); | ||
| 140 | goto lookup_protocol; | ||
| 141 | } else | ||
| 142 | goto out_rcu_unlock; | ||
| 143 | } | ||
| 144 | |||
| 145 | err = -EPERM; | ||
| 123 | if (answer->capability > 0 && !capable(answer->capability)) | 146 | if (answer->capability > 0 && !capable(answer->capability)) |
| 124 | goto out_rcu_unlock; | 147 | goto out_rcu_unlock; |
| 125 | rc = -EPROTONOSUPPORT; | ||
| 126 | if (!protocol) | ||
| 127 | goto out_rcu_unlock; | ||
| 128 | 148 | ||
| 129 | sock->ops = answer->ops; | 149 | sock->ops = answer->ops; |
| 130 | |||
| 131 | answer_prot = answer->prot; | 150 | answer_prot = answer->prot; |
| 132 | answer_no_check = answer->no_check; | 151 | answer_no_check = answer->no_check; |
| 133 | answer_flags = answer->flags; | 152 | answer_flags = answer->flags; |
| @@ -135,14 +154,14 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 135 | 154 | ||
| 136 | BUG_TRAP(answer_prot->slab != NULL); | 155 | BUG_TRAP(answer_prot->slab != NULL); |
| 137 | 156 | ||
| 138 | rc = -ENOBUFS; | 157 | err = -ENOBUFS; |
| 139 | sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); | 158 | sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); |
| 140 | if (sk == NULL) | 159 | if (sk == NULL) |
| 141 | goto out; | 160 | goto out; |
| 142 | 161 | ||
| 143 | sock_init_data(sock, sk); | 162 | sock_init_data(sock, sk); |
| 144 | 163 | ||
| 145 | rc = 0; | 164 | err = 0; |
| 146 | sk->sk_no_check = answer_no_check; | 165 | sk->sk_no_check = answer_no_check; |
| 147 | if (INET_PROTOSW_REUSE & answer_flags) | 166 | if (INET_PROTOSW_REUSE & answer_flags) |
| 148 | sk->sk_reuse = 1; | 167 | sk->sk_reuse = 1; |
| @@ -202,14 +221,14 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 202 | sk->sk_prot->hash(sk); | 221 | sk->sk_prot->hash(sk); |
| 203 | } | 222 | } |
| 204 | if (sk->sk_prot->init) { | 223 | if (sk->sk_prot->init) { |
| 205 | rc = sk->sk_prot->init(sk); | 224 | err = sk->sk_prot->init(sk); |
| 206 | if (rc) { | 225 | if (err) { |
| 207 | sk_common_release(sk); | 226 | sk_common_release(sk); |
| 208 | goto out; | 227 | goto out; |
| 209 | } | 228 | } |
| 210 | } | 229 | } |
| 211 | out: | 230 | out: |
| 212 | return rc; | 231 | return err; |
| 213 | out_rcu_unlock: | 232 | out_rcu_unlock: |
| 214 | rcu_read_unlock(); | 233 | rcu_read_unlock(); |
| 215 | goto out; | 234 | goto out; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index f15e04ad026e..fd939da090c4 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -1231,6 +1231,11 @@ int igmp6_event_report(struct sk_buff *skb) | |||
| 1231 | if (skb->pkt_type == PACKET_LOOPBACK) | 1231 | if (skb->pkt_type == PACKET_LOOPBACK) |
| 1232 | return 0; | 1232 | return 0; |
| 1233 | 1233 | ||
| 1234 | /* send our report if the MC router may not have heard this report */ | ||
| 1235 | if (skb->pkt_type != PACKET_MULTICAST && | ||
| 1236 | skb->pkt_type != PACKET_BROADCAST) | ||
| 1237 | return 0; | ||
| 1238 | |||
| 1234 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) | 1239 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) |
| 1235 | return -EINVAL; | 1240 | return -EINVAL; |
| 1236 | 1241 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index abab81f3818f..d890dfa8818f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -4743,11 +4743,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
| 4743 | struct sk_buff *skb; | 4743 | struct sk_buff *skb; |
| 4744 | long timeo; | 4744 | long timeo; |
| 4745 | 4745 | ||
| 4746 | /* Caller is allowed not to check sk->sk_err before calling. */ | ||
| 4747 | error = sock_error(sk); | ||
| 4748 | if (error) | ||
| 4749 | goto no_packet; | ||
| 4750 | |||
| 4751 | timeo = sock_rcvtimeo(sk, noblock); | 4746 | timeo = sock_rcvtimeo(sk, noblock); |
| 4752 | 4747 | ||
| 4753 | SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n", | 4748 | SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n", |
| @@ -4774,6 +4769,11 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
| 4774 | if (skb) | 4769 | if (skb) |
| 4775 | return skb; | 4770 | return skb; |
| 4776 | 4771 | ||
| 4772 | /* Caller is allowed not to check sk->sk_err before calling. */ | ||
| 4773 | error = sock_error(sk); | ||
| 4774 | if (error) | ||
| 4775 | goto no_packet; | ||
| 4776 | |||
| 4777 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 4777 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 4778 | break; | 4778 | break; |
| 4779 | 4779 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 6bc27200e6ca..268ddaf2dc0f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -261,7 +261,8 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
| 261 | * association's active path for getsockname(). | 261 | * association's active path for getsockname(). |
| 262 | */ | 262 | */ |
| 263 | if (asoc && (transport == asoc->peer.active_path)) | 263 | if (asoc && (transport == asoc->peer.active_path)) |
| 264 | af->to_sk_saddr(&transport->saddr, asoc->base.sk); | 264 | opt->pf->af->to_sk_saddr(&transport->saddr, |
| 265 | asoc->base.sk); | ||
| 265 | } else | 266 | } else |
| 266 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; | 267 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; |
| 267 | } | 268 | } |
