diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-26 21:26:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-26 21:26:05 -0700 |
| commit | 65d17d59059db7c8efff1a7fc2902612c51e42bb (patch) | |
| tree | 49f4667a86e7710332b0b36f050898f71d24d607 | |
| parent | b19738aea15fc1858ceb1180b2e334eaab12b06a (diff) | |
| parent | 4bddee2c398b538bd5871d3a57a99f06dc20e856 (diff) | |
Merge master.kernel.org:/home/davem/BK/net-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
| -rw-r--r-- | include/net/inet_common.h | 13 | ||||
| -rw-r--r-- | include/net/sock.h | 13 | ||||
| -rw-r--r-- | net/core/sock.c | 88 | ||||
| -rw-r--r-- | net/ipv4/af_inet.c | 103 | ||||
| -rw-r--r-- | net/ipv4/esp4.c | 68 | ||||
| -rw-r--r-- | net/ipv4/raw.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 4 | ||||
| -rw-r--r-- | net/ipv4/udp.c | 74 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 14 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 2 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 20 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 11 | ||||
| -rw-r--r-- | net/key/af_key.c | 9 | ||||
| -rw-r--r-- | net/sched/act_api.c | 3 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 8 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 8 | ||||
| -rw-r--r-- | net/sctp/socket.c | 4 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 9 |
18 files changed, 214 insertions, 239 deletions
diff --git a/include/net/inet_common.h b/include/net/inet_common.h index e30543604e2e..fbc1f4d140d8 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h @@ -20,27 +20,14 @@ extern int inet_dgram_connect(struct socket *sock, int addr_len, int flags); extern int inet_accept(struct socket *sock, struct socket *newsock, int flags); -extern int inet_recvmsg(struct kiocb *iocb, - struct socket *sock, - struct msghdr *ubuf, - size_t size, int flags); extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size); extern int inet_shutdown(struct socket *sock, int how); extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); -extern int inet_setsockopt(struct socket *sock, int level, - int optname, - char __user *optval, - int optlen); -extern int inet_getsockopt(struct socket *sock, int level, - int optname, - char __user *optval, - int __user *optlen); extern int inet_listen(struct socket *sock, int backlog); -extern void inet_sock_release(struct sock *sk); extern void inet_sock_destruct(struct sock *sk); extern atomic_t inet_sock_nr; diff --git a/include/net/sock.h b/include/net/sock.h index 9da91b9be903..c3277f3ecb20 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -771,6 +771,19 @@ extern ssize_t sock_no_sendpage(struct socket *sock, int flags); /* + * Functions to fill in entries in struct proto_ops when a protocol + * uses the inet style. + */ +extern int sock_common_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen); +extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size, int flags); +extern int sock_common_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, int optlen); + +extern void sk_common_release(struct sock *sk); + +/* * Default socket callbacks and setup code */ diff --git a/net/core/sock.c b/net/core/sock.c index 089972f623ab..c9b0560e6e5d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -118,6 +118,7 @@ #include <net/protocol.h> #include <linux/skbuff.h> #include <net/sock.h> +#include <net/xfrm.h> #include <linux/ipsec.h> #include <linux/filter.h> @@ -1259,6 +1260,93 @@ void sock_disable_timestamp(struct sock *sk) } EXPORT_SYMBOL(sock_disable_timestamp); +/* + * Get a socket option on an socket. + * + * FIX: POSIX 1003.1g is very ambiguous here. It states that + * asynchronous errors should be reported by getsockopt. We assume + * this means if you specify SO_ERROR (otherwise whats the point of it). + */ +int sock_common_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) +{ + struct sock *sk = sock->sk; + + return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); +} + +EXPORT_SYMBOL(sock_common_getsockopt); + +int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size, int flags) +{ + struct sock *sk = sock->sk; + int addr_len = 0; + int err; + + err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT, + flags & ~MSG_DONTWAIT, &addr_len); + if (err >= 0) + msg->msg_namelen = addr_len; + return err; +} + +EXPORT_SYMBOL(sock_common_recvmsg); + +/* + * Set socket options on an inet socket. + */ +int sock_common_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, int optlen) +{ + struct sock *sk = sock->sk; + + return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); +} + +EXPORT_SYMBOL(sock_common_setsockopt); + +void sk_common_release(struct sock *sk) +{ + if (sk->sk_prot->destroy) + sk->sk_prot->destroy(sk); + + /* + * Observation: when sock_common_release is called, processes have + * no access to socket. But net still has. + * Step one, detach it from networking: + * + * A. Remove from hash tables. + */ + + sk->sk_prot->unhash(sk); + + /* + * In this point socket cannot receive new packets, but it is possible + * that some packets are in flight because some CPU runs receiver and + * did hash table lookup before we unhashed socket. They will achieve + * receive queue and will be purged by socket destructor. + * + * Also we still have packets pending on receive queue and probably, + * our own packets waiting in device queues. sock_destroy will drain + * receive queue, but transmitted packets will delay socket destruction + * until the last reference will be released. + */ + + sock_orphan(sk); + + xfrm_sk_free_policy(sk); + +#ifdef INET_REFCNT_DEBUG + if (atomic_read(&sk->sk_refcnt) != 1) + printk(KERN_DEBUG "Destruction of the socket %p delayed, c=%d\n", + sk, atomic_read(&sk->sk_refcnt)); +#endif + sock_put(sk); +} + +EXPORT_SYMBOL(sk_common_release); + EXPORT_SYMBOL(__lock_sock); EXPORT_SYMBOL(__release_sock); EXPORT_SYMBOL(sk_alloc); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index caa8632509b5..1939a76e6308 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -166,46 +166,6 @@ void inet_sock_destruct(struct sock *sk) #endif } -void inet_sock_release(struct sock *sk) -{ - if (sk->sk_prot->destroy) - sk->sk_prot->destroy(sk); - - /* Observation: when inet_sock_release is called, processes have - * no access to socket. But net still has. - * Step one, detach it from networking: - * - * A. Remove from hash tables. - */ - - sk->sk_prot->unhash(sk); - - /* In this point socket cannot receive new packets, - * but it is possible that some packets are in flight - * because some CPU runs receiver and did hash table lookup - * before we unhashed socket. They will achieve receive queue - * and will be purged by socket destructor. - * - * Also we still have packets pending on receive - * queue and probably, our own packets waiting in device queues. - * sock_destroy will drain receive queue, but transmitted - * packets will delay socket destruction until the last reference - * will be released. - */ - - sock_orphan(sk); - - xfrm_sk_free_policy(sk); - -#ifdef INET_REFCNT_DEBUG - if (atomic_read(&sk->sk_refcnt) != 1) - printk(KERN_DEBUG "Destruction inet %p delayed, c=%d\n", - sk, atomic_read(&sk->sk_refcnt)); -#endif - sock_put(sk); -} - - /* * The routines beyond this point handle the behaviour of an AF_INET * socket object. Mostly it punts to the subprotocols of IP to do @@ -213,33 +173,6 @@ void inet_sock_release(struct sock *sk) */ /* - * Set socket options on an inet socket. - */ -int inet_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) -{ - struct sock *sk = sock->sk; - - return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); -} - -/* - * Get a socket option on an AF_INET socket. - * - * FIX: POSIX 1003.1g is very ambiguous here. It states that - * asynchronous errors should be reported by getsockopt. We assume - * this means if you specify SO_ERROR (otherwise whats the point of it). - */ - -int inet_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) -{ - struct sock *sk = sock->sk; - - return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); -} - -/* * Automatically bind an unbound socket. */ @@ -422,7 +355,7 @@ static int inet_create(struct socket *sock, int protocol) if (sk->sk_prot->init) { err = sk->sk_prot->init(sk); if (err) - inet_sock_release(sk); + sk_common_release(sk); } out: return err; @@ -729,22 +662,6 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr, return 0; } - -int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, - size_t size, int flags) -{ - struct sock *sk = sock->sk; - int addr_len = 0; - int err; - - err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT, - flags & ~MSG_DONTWAIT, &addr_len); - if (err >= 0) - msg->msg_namelen = addr_len; - return err; -} - - int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size) { @@ -891,10 +808,10 @@ struct proto_ops inet_stream_ops = { .ioctl = inet_ioctl, .listen = inet_listen, .shutdown = inet_shutdown, - .setsockopt = inet_setsockopt, - .getsockopt = inet_getsockopt, + .setsockopt = sock_common_setsockopt, + .getsockopt = sock_common_getsockopt, .sendmsg = inet_sendmsg, - .recvmsg = inet_recvmsg, + .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = tcp_sendpage }; @@ -906,16 +823,16 @@ struct proto_ops inet_dgram_ops = { .bind = inet_bind, .connect = inet_dgram_connect, .socketpair = sock_no_socketpair, - .accept = sock_no_accept, + .accept = inet_accept, .getname = inet_getname, .poll = datagram_poll, .ioctl = inet_ioctl, .listen = sock_no_listen, .shutdown = inet_shutdown, - .setsockopt = inet_setsockopt, - .getsockopt = inet_getsockopt, + .setsockopt = sock_common_setsockopt, + .getsockopt = sock_common_getsockopt, .sendmsg = inet_sendmsg, - .recvmsg = inet_recvmsg, + .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = inet_sendpage, }; @@ -1242,17 +1159,13 @@ EXPORT_SYMBOL(inet_dgram_connect); EXPORT_SYMBOL(inet_dgram_ops); EXPORT_SYMBOL(inet_family_ops); EXPORT_SYMBOL(inet_getname); -EXPORT_SYMBOL(inet_getsockopt); EXPORT_SYMBOL(inet_ioctl); EXPORT_SYMBOL(inet_listen); -EXPORT_SYMBOL(inet_recvmsg); EXPORT_SYMBOL(inet_register_protosw); EXPORT_SYMBOL(inet_release); EXPORT_SYMBOL(inet_sendmsg); -EXPORT_SYMBOL(inet_setsockopt); EXPORT_SYMBOL(inet_shutdown); EXPORT_SYMBOL(inet_sock_destruct); -EXPORT_SYMBOL(inet_sock_release); EXPORT_SYMBOL(inet_stream_connect); EXPORT_SYMBOL(inet_stream_ops); EXPORT_SYMBOL(inet_unregister_protosw); diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 9f078254fcbd..1fa9a9b98d83 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -94,8 +94,9 @@ int esp_output(struct sk_buff **pskb) if (x->props.mode) { top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len); esph = (struct ip_esp_hdr*)(top_iph+1); - if (encap && encap->encap_type) { + if (encap) { switch (encap->encap_type) { + default: case UDP_ENCAP_ESPINUDP: uh = (struct udphdr*) esph; esph = (struct ip_esp_hdr*)(uh+1); @@ -106,15 +107,8 @@ int esp_output(struct sk_buff **pskb) udpdata32 = (u32*)(uh+1); udpdata32[0] = udpdata32[1] = 0; esph = (struct ip_esp_hdr*)(udpdata32+2); - alen += 2; top_iph->protocol = IPPROTO_UDP; break; - default: - printk(KERN_INFO - "esp_output(): Unhandled encap: %u\n", - encap->encap_type); - top_iph->protocol = IPPROTO_ESP; - break; } } else top_iph->protocol = IPPROTO_ESP; @@ -137,8 +131,9 @@ int esp_output(struct sk_buff **pskb) esph = (struct ip_esp_hdr*)skb_push(*pskb, x->props.header_len); top_iph = (struct iphdr*)skb_push(*pskb, iph->ihl*4); memcpy(top_iph, &tmp_iph, iph->ihl*4); - if (encap && encap->encap_type) { + if (encap) { switch (encap->encap_type) { + default: case UDP_ENCAP_ESPINUDP: uh = (struct udphdr*) esph; esph = (struct ip_esp_hdr*)(uh+1); @@ -149,15 +144,8 @@ int esp_output(struct sk_buff **pskb) udpdata32 = (u32*)(uh+1); udpdata32[0] = udpdata32[1] = 0; esph = (struct ip_esp_hdr*)(udpdata32+2); - alen += 2; top_iph->protocol = IPPROTO_UDP; break; - default: - printk(KERN_INFO - "esp_output(): Unhandled encap: %u\n", - encap->encap_type); - top_iph->protocol = IPPROTO_ESP; - break; } } else top_iph->protocol = IPPROTO_ESP; @@ -313,28 +301,14 @@ int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu switch (decap->decap_type) { case UDP_ENCAP_ESPINUDP: case UDP_ENCAP_ESPINUDP_NON_IKE: - - if ((void*)uh == (void*)esph) { - printk(KERN_DEBUG - "esp_input(): Got ESP; expecting ESPinUDP\n"); - break; - } - encap_data->proto = AF_INET; encap_data->saddr.a4 = iph->saddr; encap_data->sport = uh->source; encap_len = (void*)esph - (void*)uh; - if (encap_len != sizeof(*uh)) - printk(KERN_DEBUG - "esp_input(): UDP -> ESP: too much room: %d\n", - encap_len); break; default: - printk(KERN_INFO - "esp_input(): processing unknown encap type: %u\n", - decap->decap_type); - break; + goto out; } } @@ -367,11 +341,8 @@ int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct if (encap->encap_type != decap->decap_type) return -EINVAL; - /* Next, if we don't have an encap type, then ignore it */ - if (!encap->encap_type) - return 0; - switch (encap->encap_type) { + default: case UDP_ENCAP_ESPINUDP: case UDP_ENCAP_ESPINUDP_NON_IKE: /* @@ -408,11 +379,6 @@ int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct skb->ip_summed = CHECKSUM_UNNECESSARY; break; - default: - printk(KERN_INFO - "esp4_post_input(): Unhandled encap type: %u\n", - encap->encap_type); - break; } } return 0; @@ -549,20 +515,14 @@ int esp_init_state(struct xfrm_state *x, void *args) if (x->encap) { struct xfrm_encap_tmpl *encap = x->encap; - if (encap->encap_type) { - switch (encap->encap_type) { - case UDP_ENCAP_ESPINUDP: - x->props.header_len += sizeof(struct udphdr); - break; - case UDP_ENCAP_ESPINUDP_NON_IKE: - x->props.header_len += sizeof(struct udphdr) + 2 * sizeof(u32); - break; - default: - printk (KERN_INFO - "esp_init_state(): Unhandled encap type: %u\n", - encap->encap_type); - break; - } + switch (encap->encap_type) { + default: + case UDP_ENCAP_ESPINUDP: + x->props.header_len += sizeof(struct udphdr); + break; + case UDP_ENCAP_ESPINUDP_NON_IKE: + x->props.header_len += sizeof(struct udphdr) + 2 * sizeof(u32); + break; } } x->data = esp; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b941c00ddd86..ac04153be863 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -480,7 +480,7 @@ static void raw_close(struct sock *sk, long timeout) */ ip_ra_control(sk, 0, NULL); - inet_sock_release(sk); + sk_common_release(sk); } /* This gets rid of all the nasties in af_inet. -DaveM */ diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 35ca34b6b052..51c1230c643f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2094,7 +2094,7 @@ static int tcp_v4_init_sock(struct sock *sk) return 0; } -static int tcp_v4_destroy_sock(struct sock *sk) +int tcp_v4_destroy_sock(struct sock *sk) { struct tcp_opt *tp = tcp_sk(sk); @@ -2118,6 +2118,8 @@ static int tcp_v4_destroy_sock(struct sock *sk) return 0; } +EXPORT_SYMBOL(tcp_v4_destroy_sock); + #ifdef CONFIG_PROC_FS /* Proc filesystem TCP sock list dumping. */ diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index a583751680c6..bfa78d5ee608 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -931,7 +931,7 @@ int udp_disconnect(struct sock *sk, int flags) static void udp_close(struct sock *sk, long timeout) { - inet_sock_release(sk); + sk_common_release(sk); } /* return: @@ -964,6 +964,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) len = skb->tail - udpdata; switch (encap_type) { + default: case UDP_ENCAP_ESPINUDP: /* Check if this is a keepalive packet. If so, eat it. */ if (len == 1 && udpdata[0] == 0xff) { @@ -975,34 +976,6 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) /* Must be an IKE packet.. pass it through */ return 1; - decaps: - /* At this point we are sure that this is an ESPinUDP packet, - * so we need to remove 'len' bytes from the packet (the UDP - * header and optional ESP marker bytes) and then modify the - * protocol to ESP, and then call into the transform receiver. - */ - - /* Now we can update and verify the packet length... */ - iph = skb->nh.iph; - iphlen = iph->ihl << 2; - iph->tot_len = htons(ntohs(iph->tot_len) - len); - if (skb->len < iphlen + len) { - /* packet is too small!?! */ - return 0; - } - - /* pull the data buffer up to the ESP header and set the - * transport header to point to ESP. Keep UDP on the stack - * for later. - */ - skb->h.raw = skb_pull(skb, len); - - /* modify the protocol (it's ESP!) */ - iph->protocol = IPPROTO_ESP; - - /* and let the caller know to send this into the ESP processor... */ - return -1; - case UDP_ENCAP_ESPINUDP_NON_IKE: /* Check if this is a keepalive packet. If so, eat it. */ if (len == 1 && udpdata[0] == 0xff) { @@ -1012,17 +985,37 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) /* ESP Packet with Non-IKE marker */ len = sizeof(struct udphdr) + 2 * sizeof(u32); - goto decaps; } else /* Must be an IKE packet.. pass it through */ return 1; + } - default: - if (net_ratelimit()) - printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n", - encap_type); - return 1; + /* At this point we are sure that this is an ESPinUDP packet, + * so we need to remove 'len' bytes from the packet (the UDP + * header and optional ESP marker bytes) and then modify the + * protocol to ESP, and then call into the transform receiver. + */ + + /* Now we can update and verify the packet length... */ + iph = skb->nh.iph; + iphlen = iph->ihl << 2; + iph->tot_len = htons(ntohs(iph->tot_len) - len); + if (skb->len < iphlen + len) { + /* packet is too small!?! */ + return 0; } + + /* pull the data buffer up to the ESP header and set the + * transport header to point to ESP. Keep UDP on the stack + * for later. + */ + skb->h.raw = skb_pull(skb, len); + + /* modify the protocol (it's ESP!) */ + iph->protocol = IPPROTO_ESP; + + /* and let the caller know to send this into the ESP processor... */ + return -1; #endif } @@ -1297,7 +1290,16 @@ static int udp_setsockopt(struct sock *sk, int level, int optname, break; case UDP_ENCAP: - up->encap_type = val; + switch (val) { + case 0: + case UDP_ENCAP_ESPINUDP: + case UDP_ENCAP_ESPINUDP_NON_IKE: + up->encap_type = val; + break; + default: + err = -ENOPROTOOPT; + break; + } break; default: diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 33e39d2201c1..0cf2ee00d257 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -250,7 +250,7 @@ static int inet6_create(struct socket *sock, int protocol) if (sk->sk_prot->init) { int err = sk->sk_prot->init(sk); if (err != 0) { - inet_sock_release(sk); + sk_common_release(sk); return err; } } @@ -510,10 +510,10 @@ struct proto_ops inet6_stream_ops = { .ioctl = inet6_ioctl, /* must change */ .listen = inet_listen, /* ok */ .shutdown = inet_shutdown, /* ok */ - .setsockopt = inet_setsockopt, /* ok */ - .getsockopt = inet_getsockopt, /* ok */ + .setsockopt = sock_common_setsockopt, /* ok */ + .getsockopt = sock_common_getsockopt, /* ok */ .sendmsg = inet_sendmsg, /* ok */ - .recvmsg = inet_recvmsg, /* ok */ + .recvmsg = sock_common_recvmsg, /* ok */ .mmap = sock_no_mmap, .sendpage = tcp_sendpage }; @@ -531,10 +531,10 @@ struct proto_ops inet6_dgram_ops = { .ioctl = inet6_ioctl, /* must change */ .listen = sock_no_listen, /* ok */ .shutdown = inet_shutdown, /* ok */ - .setsockopt = inet_setsockopt, /* ok */ - .getsockopt = inet_getsockopt, /* ok */ + .setsockopt = sock_common_setsockopt, /* ok */ + .getsockopt = sock_common_getsockopt, /* ok */ .sendmsg = inet_sendmsg, /* ok */ - .recvmsg = inet_recvmsg, /* ok */ + .recvmsg = sock_common_recvmsg, /* ok */ .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 079d3cac18e0..447b142d6327 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -900,7 +900,7 @@ static void rawv6_close(struct sock *sk, long timeout) if (inet_sk(sk)->num == IPPROTO_RAW) ip6_ra_control(sk, -1, NULL); - inet_sock_release(sk); + sk_common_release(sk); } static int rawv6_init_sk(struct sock *sk) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a564266be2ff..80ae80db93e2 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1892,25 +1892,9 @@ static int tcp_v6_init_sock(struct sock *sk) static int tcp_v6_destroy_sock(struct sock *sk) { - struct tcp_opt *tp = tcp_sk(sk); - - tcp_clear_xmit_timers(sk); - - /* Cleanup up the write buffer. */ - sk_stream_writequeue_purge(sk); - - /* Cleans up our, hopefully empty, out_of_order_queue. */ - __skb_queue_purge(&tp->out_of_order_queue); - - /* Clean prequeue, it must be empty really */ - __skb_queue_purge(&tp->ucopy.prequeue); - - /* Clean up a referenced TCP bind bucket. */ - if (tcp_sk(sk)->bind_hash) - tcp_put_port(sk); - - atomic_dec(&tcp_sockets_allocated); + extern int tcp_v4_destroy_sock(struct sock *sk); + tcp_v4_destroy_sock(sk); return inet6_destroy_sock(sk); } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 52d2b8b3024e..9a6bc46b532b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -358,7 +358,7 @@ out: static void udpv6_close(struct sock *sk, long timeout) { - inet_sock_release(sk); + sk_common_release(sk); } /* @@ -1044,7 +1044,14 @@ static int udpv6_setsockopt(struct sock *sk, int level, int optname, break; case UDP_ENCAP: - up->encap_type = val; + switch (val) { + case 0: + up->encap_type = val; + break; + default: + err = -ENOPROTOOPT; + break; + } break; default: diff --git a/net/key/af_key.c b/net/key/af_key.c index 645b42564bd2..68497a25070e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -1075,6 +1075,15 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]; natt->encap_type = n_type->sadb_x_nat_t_type_type; + switch (natt->encap_type) { + case UDP_ENCAP_ESPINUDP: + case UDP_ENCAP_ESPINUDP_NON_IKE: + break; + default: + err = -ENOPROTOOPT; + goto out; + } + if (ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]) { struct sadb_x_nat_t_port* n_port = ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 91076dc78b5d..1e3bf5b42715 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -610,6 +610,7 @@ int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) unsigned char *b; struct nlmsghdr *nlh; struct tcamsg *t; + struct netlink_callback dcb; struct rtattr *x; struct rtattr *tb[TCA_ACT_MAX+1]; struct rtattr *kind = NULL; @@ -646,7 +647,7 @@ int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); - err = a->ops->walk(skb, NULL, RTM_DELACTION, a); + err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); if (0 > err ) { goto rtattr_failure; } diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index af402f7d492c..1adfd8cfd051 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -641,7 +641,7 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk, #endif if (newsk->sk_prot->init(newsk)) { - inet_sock_release(newsk); + sk_common_release(newsk); newsk = NULL; } @@ -882,10 +882,10 @@ static struct proto_ops inet6_seqpacket_ops = { .ioctl = inet6_ioctl, .listen = sctp_inet_listen, .shutdown = inet_shutdown, - .setsockopt = inet_setsockopt, - .getsockopt = inet_getsockopt, + .setsockopt = sock_common_setsockopt, + .getsockopt = sock_common_getsockopt, .sendmsg = inet_sendmsg, - .recvmsg = inet_recvmsg, + .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, }; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index f2abbf48a7d3..c0d13711ea8c 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -603,7 +603,7 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk, #endif if (newsk->sk_prot->init(newsk)) { - inet_sock_release(newsk); + sk_common_release(newsk); newsk = NULL; } @@ -846,10 +846,10 @@ struct proto_ops inet_seqpacket_ops = { .ioctl = inet_ioctl, .listen = sctp_inet_listen, .shutdown = inet_shutdown, /* Looks harmless. */ - .setsockopt = inet_setsockopt, /* IP_SOL IP_OPTION is a problem. */ - .getsockopt = inet_getsockopt, + .setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem. */ + .getsockopt = sock_common_getsockopt, .sendmsg = inet_sendmsg, - .recvmsg = inet_recvmsg, + .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, }; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d1b683952499..1b33d4d7b574 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -945,11 +945,11 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) sctp_local_bh_disable(); sctp_bh_lock_sock(sk); - /* Hold the sock, since inet_sock_release() will put sock_put() + /* Hold the sock, since sk_common_release() will put sock_put() * and we have just a little more cleanup. */ sock_hold(sk); - inet_sock_release(sk); + sk_common_release(sk); sctp_bh_unlock_sock(sk); sctp_local_bh_enable(); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 15bf2fd27825..b917b5a77b35 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -78,6 +78,15 @@ static int verify_encap_tmpl(struct rtattr **xfrma) if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap)) return -EINVAL; + encap = RTA_DATA(rt); + switch (encap->encap_type) { + case UDP_ENCAP_ESPINUDP: + case UDP_ENCAP_ESPINUDP_NON_IKE: + break; + default: + return -ENOPROTOOPT; + } + return 0; } |
