linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / include / net / sock.h
index 54ea26c..f501a40 100644 (file)
@@ -62,7 +62,7 @@
  */
 
 /* Define this to get the SOCK_DBG debugging facility. */
-//#define SOCK_DEBUGGING
+#define SOCK_DEBUGGING
 #ifdef SOCK_DEBUGGING
 #define SOCK_DEBUG(sk, msg...) do { if ((sk) && sock_flag((sk), SOCK_DBG)) \
                                        printk(KERN_DEBUG msg); } while (0)
@@ -116,9 +116,9 @@ struct sock_common {
        unsigned int            skc_hash;
        struct proto            *skc_prot;
        xid_t                   skc_xid;
-       struct vx_info  *skc_vx_info;
+       struct vx_info          *skc_vx_info;
        nid_t                   skc_nid;
-       struct nx_info  *skc_nx_info;
+       struct nx_info          *skc_nx_info;
 };
 
 /**
@@ -165,7 +165,7 @@ struct sock_common {
   *    @sk_timer: sock cleanup timer
   *    @sk_stamp: time stamp of last packet received
   *    @sk_socket: Identd and reporting IO signals
-  *    @sk_user_data: RPC and Tux layer private data
+  *    @sk_user_data: RPC layer private data
   *    @sk_sndmsg_page: cached page for sendmsg
   *    @sk_sndmsg_off: cached offset for sendmsg
   *    @sk_send_head: front of stuff to transmit
@@ -175,7 +175,6 @@ struct sock_common {
   *    @sk_data_ready: callback to indicate there is data to be processed
   *    @sk_write_space: callback to indicate there is bf sending space available
   *    @sk_error_report: callback to indicate errors (e.g. %MSG_ERRQUEUE)
-  *    @sk_create_child - callback to get new socket events
   *    @sk_backlog_rcv: callback to process the backlog
   *    @sk_destruct: called at sock freeing time, i.e. when all refcnt == 0
  */
@@ -219,7 +218,6 @@ struct sock {
        gfp_t                   sk_allocation;
        int                     sk_sndbuf;
        int                     sk_route_caps;
-       int                     sk_rcvlowat;
        unsigned long           sk_flags;
        unsigned long           sk_lingertime;
        /*
@@ -240,6 +238,7 @@ struct sock {
        unsigned short          sk_max_ack_backlog;
        __u32                   sk_priority;
        struct ucred            sk_peercred;
+       int                     sk_rcvlowat;
        long                    sk_rcvtimeo;
        long                    sk_sndtimeo;
        struct sk_filter        *sk_filter;
@@ -259,7 +258,6 @@ struct sock {
        void                    (*sk_error_report)(struct sock *sk);
        int                     (*sk_backlog_rcv)(struct sock *sk,
                                                  struct sk_buff *skb);  
-       void                    (*sk_create_child)(struct sock *sk, struct sock *newsk);
        void                    (*sk_destruct)(struct sock *sk);
 };
 
@@ -289,7 +287,7 @@ static inline int sk_unhashed(const struct sock *sk)
 
 static inline int sk_hashed(const struct sock *sk)
 {
-       return !sk_unhashed(sk);
+       return sk->sk_node.pprev != NULL;
 }
 
 static __inline__ void sk_node_init(struct hlist_node *node)
@@ -464,7 +462,6 @@ static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
 
 static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
 {
-       skb_truesize_check(skb);
        sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
        sk->sk_wmem_queued   -= skb->truesize;
        sk->sk_forward_alloc += skb->truesize;
@@ -531,14 +528,6 @@ struct proto {
        int                     (*getsockopt)(struct sock *sk, int level, 
                                        int optname, char __user *optval, 
                                        int __user *option);     
-       int                     (*compat_setsockopt)(struct sock *sk,
-                                       int level,
-                                       int optname, char __user *optval,
-                                       int optlen);
-       int                     (*compat_getsockopt)(struct sock *sk,
-                                       int level,
-                                       int optname, char __user *optval,
-                                       int __user *option);
        int                     (*sendmsg)(struct kiocb *iocb, struct sock *sk,
                                           struct msghdr *msg, size_t len);
        int                     (*recvmsg)(struct kiocb *iocb, struct sock *sk,
@@ -761,7 +750,7 @@ extern struct sock          *sk_alloc(int family,
                                          gfp_t priority,
                                          struct proto *prot, int zero_it);
 extern void                    sk_free(struct sock *sk);
-extern struct sock             *sk_clone(struct sock *sk,
+extern struct sock             *sk_clone(const struct sock *sk,
                                          const gfp_t priority);
 
 extern struct sk_buff          *sock_wmalloc(struct sock *sk,
@@ -835,10 +824,6 @@ 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 int compat_sock_common_getsockopt(struct socket *sock, int level,
-               int optname, char __user *optval, int __user *optlen);
-extern int compat_sock_common_setsockopt(struct socket *sock, int level,
-               int optname, char __user *optval, int optlen);
 
 extern void sk_common_release(struct sock *sk);
 
@@ -949,7 +934,28 @@ static inline void sock_put(struct sock *sk)
                sk_free(sk);
 }
 
-extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb);
+static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
+{
+       int rc = NET_RX_SUCCESS;
+
+       if (sk_filter(sk, skb, 0))
+               goto discard_and_relse;
+
+       skb->dev = NULL;
+
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               rc = sk->sk_backlog_rcv(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
+out:
+       sock_put(sk);
+       return rc;
+discard_and_relse:
+       kfree_skb(skb);
+       goto out;
+}
 
 /* Detach socket from process context.
  * Announce socket dead, detach it from wait queue and inode.
@@ -1034,9 +1040,33 @@ sk_dst_reset(struct sock *sk)
        write_unlock(&sk->sk_dst_lock);
 }
 
-extern struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie);
+static inline struct dst_entry *
+__sk_dst_check(struct sock *sk, u32 cookie)
+{
+       struct dst_entry *dst = sk->sk_dst_cache;
+
+       if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
+               sk->sk_dst_cache = NULL;
+               dst_release(dst);
+               return NULL;
+       }
+
+       return dst;
+}
 
-extern struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie);
+static inline struct dst_entry *
+sk_dst_check(struct sock *sk, u32 cookie)
+{
+       struct dst_entry *dst = sk_dst_get(sk);
+
+       if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
+               sk_dst_reset(sk);
+               dst_release(dst);
+               return NULL;
+       }
+
+       return dst;
+}
 
 static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
 {
@@ -1106,9 +1136,61 @@ extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
 
 extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
 
+#if defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)
 extern int vnet_active;
+#endif
+
+static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+       int err = 0;
+       int skb_len;
+
+#if defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)
+       /* Silently drop if VNET is active (if INET bind() has been
+        * overridden) and the context is not entitled to read the
+        * packet.
+        */
+       if (vnet_active &&
+           (int) sk->sk_xid > 0 && sk->sk_xid != skb->xid) {
+               err = -EPERM;
+               goto out;
+       }
+#endif
+
+       /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
+          number of warnings when compiling with -W --ANK
+        */
+       if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
+           (unsigned)sk->sk_rcvbuf) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       /* It would be deadlock, if sock_queue_rcv_skb is used
+          with socket lock! We assume that users of this
+          function are lock free.
+       */
+       err = sk_filter(sk, skb, 1);
+       if (err)
+               goto out;
+
+       skb->dev = NULL;
+       skb_set_owner_r(skb, sk);
 
-extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+       /* Cache the SKB length before we tack it onto the receive
+        * queue.  Once it is added it no longer belongs to us and
+        * may be freed by other threads of control pulling packets
+        * from the queue.
+        */
+       skb_len = skb->len;
+
+       skb_queue_tail(&sk->sk_receive_queue, skb);
+
+       if (!sock_flag(sk, SOCK_DEAD))
+               sk->sk_data_ready(sk, skb_len);
+out:
+       return err;
+}
 
 static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 {