Commit b3c6aeb3 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

parents af2eb17b af1afe86
...@@ -228,13 +228,14 @@ static int inet_create(struct socket *sock, int protocol) ...@@ -228,13 +228,14 @@ static int inet_create(struct socket *sock, int protocol)
unsigned char answer_flags; unsigned char answer_flags;
char answer_no_check; char answer_no_check;
int try_loading_module = 0; int try_loading_module = 0;
int err = -ESOCKTNOSUPPORT; int err;
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
/* Look for the requested type/protocol pair. */ /* Look for the requested type/protocol pair. */
answer = NULL; answer = NULL;
lookup_protocol: lookup_protocol:
err = -ESOCKTNOSUPPORT;
rcu_read_lock(); rcu_read_lock();
list_for_each_rcu(p, &inetsw[sock->type]) { list_for_each_rcu(p, &inetsw[sock->type]) {
answer = list_entry(p, struct inet_protosw, list); answer = list_entry(p, struct inet_protosw, list);
...@@ -252,6 +253,7 @@ lookup_protocol: ...@@ -252,6 +253,7 @@ lookup_protocol:
if (IPPROTO_IP == answer->protocol) if (IPPROTO_IP == answer->protocol)
break; break;
} }
err = -EPROTONOSUPPORT;
answer = NULL; answer = NULL;
} }
...@@ -280,9 +282,6 @@ lookup_protocol: ...@@ -280,9 +282,6 @@ lookup_protocol:
err = -EPERM; err = -EPERM;
if (answer->capability > 0 && !capable(answer->capability)) if (answer->capability > 0 && !capable(answer->capability))
goto out_rcu_unlock; goto out_rcu_unlock;
err = -EPROTONOSUPPORT;
if (!protocol)
goto out_rcu_unlock;
sock->ops = answer->ops; sock->ops = answer->ops;
answer_prot = answer->prot; answer_prot = answer->prot;
......
...@@ -897,6 +897,9 @@ int igmp_rcv(struct sk_buff *skb) ...@@ -897,6 +897,9 @@ int igmp_rcv(struct sk_buff *skb)
/* Is it our report looped back? */ /* Is it our report looped back? */
if (((struct rtable*)skb->dst)->fl.iif == 0) if (((struct rtable*)skb->dst)->fl.iif == 0)
break; break;
/* don't rely on MC router hearing unicast reports */
if (skb->pkt_type == PACKET_MULTICAST ||
skb->pkt_type == PACKET_BROADCAST)
igmp_heard_report(in_dev, ih->group); igmp_heard_report(in_dev, ih->group);
break; break;
case IGMP_PIM: case IGMP_PIM:
......
...@@ -92,10 +92,13 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -92,10 +92,13 @@ static int inet6_create(struct socket *sock, int protocol)
struct proto *answer_prot; struct proto *answer_prot;
unsigned char answer_flags; unsigned char answer_flags;
char answer_no_check; char answer_no_check;
int rc; int try_loading_module = 0;
int err;
/* Look for the requested type/protocol pair. */ /* Look for the requested type/protocol pair. */
answer = NULL; answer = NULL;
lookup_protocol:
err = -ESOCKTNOSUPPORT;
rcu_read_lock(); rcu_read_lock();
list_for_each_rcu(p, &inetsw6[sock->type]) { list_for_each_rcu(p, &inetsw6[sock->type]) {
answer = list_entry(p, struct inet_protosw, list); answer = list_entry(p, struct inet_protosw, list);
...@@ -113,21 +116,37 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -113,21 +116,37 @@ static int inet6_create(struct socket *sock, int protocol)
if (IPPROTO_IP == answer->protocol) if (IPPROTO_IP == answer->protocol)
break; break;
} }
err = -EPROTONOSUPPORT;
answer = NULL; answer = NULL;
} }
rc = -ESOCKTNOSUPPORT; if (!answer) {
if (!answer) if (try_loading_module < 2) {
rcu_read_unlock();
/*
* Be more specific, e.g. net-pf-10-proto-132-type-1
* (net-pf-PF_INET6-proto-IPPROTO_SCTP-type-SOCK_STREAM)
*/
if (++try_loading_module == 1)
request_module("net-pf-%d-proto-%d-type-%d",
PF_INET6, protocol, sock->type);
/*
* Fall back to generic, e.g. net-pf-10-proto-132
* (net-pf-PF_INET6-proto-IPPROTO_SCTP)
*/
else
request_module("net-pf-%d-proto-%d",
PF_INET6, protocol);
goto lookup_protocol;
} else
goto out_rcu_unlock; goto out_rcu_unlock;
rc = -EPERM; }
err = -EPERM;
if (answer->capability > 0 && !capable(answer->capability)) if (answer->capability > 0 && !capable(answer->capability))
goto out_rcu_unlock; goto out_rcu_unlock;
rc = -EPROTONOSUPPORT;
if (!protocol)
goto out_rcu_unlock;
sock->ops = answer->ops; sock->ops = answer->ops;
answer_prot = answer->prot; answer_prot = answer->prot;
answer_no_check = answer->no_check; answer_no_check = answer->no_check;
answer_flags = answer->flags; answer_flags = answer->flags;
...@@ -135,14 +154,14 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -135,14 +154,14 @@ static int inet6_create(struct socket *sock, int protocol)
BUG_TRAP(answer_prot->slab != NULL); BUG_TRAP(answer_prot->slab != NULL);
rc = -ENOBUFS; err = -ENOBUFS;
sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
if (sk == NULL) if (sk == NULL)
goto out; goto out;
sock_init_data(sock, sk); sock_init_data(sock, sk);
rc = 0; err = 0;
sk->sk_no_check = answer_no_check; sk->sk_no_check = answer_no_check;
if (INET_PROTOSW_REUSE & answer_flags) if (INET_PROTOSW_REUSE & answer_flags)
sk->sk_reuse = 1; sk->sk_reuse = 1;
...@@ -202,14 +221,14 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -202,14 +221,14 @@ static int inet6_create(struct socket *sock, int protocol)
sk->sk_prot->hash(sk); sk->sk_prot->hash(sk);
} }
if (sk->sk_prot->init) { if (sk->sk_prot->init) {
rc = sk->sk_prot->init(sk); err = sk->sk_prot->init(sk);
if (rc) { if (err) {
sk_common_release(sk); sk_common_release(sk);
goto out; goto out;
} }
} }
out: out:
return rc; return err;
out_rcu_unlock: out_rcu_unlock:
rcu_read_unlock(); rcu_read_unlock();
goto out; goto out;
......
...@@ -1231,6 +1231,11 @@ int igmp6_event_report(struct sk_buff *skb) ...@@ -1231,6 +1231,11 @@ int igmp6_event_report(struct sk_buff *skb)
if (skb->pkt_type == PACKET_LOOPBACK) if (skb->pkt_type == PACKET_LOOPBACK)
return 0; return 0;
/* send our report if the MC router may not have heard this report */
if (skb->pkt_type != PACKET_MULTICAST &&
skb->pkt_type != PACKET_BROADCAST)
return 0;
if (!pskb_may_pull(skb, sizeof(struct in6_addr))) if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
return -EINVAL; return -EINVAL;
......
...@@ -4743,11 +4743,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, ...@@ -4743,11 +4743,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
struct sk_buff *skb; struct sk_buff *skb;
long timeo; long timeo;
/* Caller is allowed not to check sk->sk_err before calling. */
error = sock_error(sk);
if (error)
goto no_packet;
timeo = sock_rcvtimeo(sk, noblock); timeo = sock_rcvtimeo(sk, noblock);
SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n", 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,6 +4769,11 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
if (skb) if (skb)
return skb; return skb;
/* Caller is allowed not to check sk->sk_err before calling. */
error = sock_error(sk);
if (error)
goto no_packet;
if (sk->sk_shutdown & RCV_SHUTDOWN) if (sk->sk_shutdown & RCV_SHUTDOWN)
break; break;
......
...@@ -261,7 +261,8 @@ void sctp_transport_route(struct sctp_transport *transport, ...@@ -261,7 +261,8 @@ void sctp_transport_route(struct sctp_transport *transport,
* association's active path for getsockname(). * association's active path for getsockname().
*/ */
if (asoc && (transport == asoc->peer.active_path)) if (asoc && (transport == asoc->peer.active_path))
af->to_sk_saddr(&transport->saddr, asoc->base.sk); opt->pf->af->to_sk_saddr(&transport->saddr,
asoc->base.sk);
} else } else
transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment