summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_common.h13
-rw-r--r--include/net/sock.h13
-rw-r--r--net/core/sock.c88
-rw-r--r--net/ipv4/af_inet.c103
-rw-r--r--net/ipv4/esp4.c68
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/tcp_ipv4.c4
-rw-r--r--net/ipv4/udp.c74
-rw-r--r--net/ipv6/af_inet6.c14
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/ipv6/tcp_ipv6.c20
-rw-r--r--net/ipv6/udp.c11
-rw-r--r--net/key/af_key.c9
-rw-r--r--net/sched/act_api.c3
-rw-r--r--net/sctp/ipv6.c8
-rw-r--r--net/sctp/protocol.c8
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/xfrm/xfrm_user.c9
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;
}