]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv4/raw.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-2.6.git] / net / ipv4 / raw.c
index a3002fe65b7f4a345c1333c4d7f36392bee3b172..1d0c97c8712d30f01d538f874fd2cf491e2032ff 100644 (file)
@@ -5,8 +5,6 @@
  *
  *             RAW - implementation of IP "raw" sockets.
  *
- * Version:    $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
- *
  * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
 #include <linux/netfilter_ipv4.h>
 
 static struct raw_hashinfo raw_v4_hashinfo = {
-       .lock = __RW_LOCK_UNLOCKED(),
+       .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock),
 };
 
-void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h)
+void raw_hash_sk(struct sock *sk)
 {
+       struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
        struct hlist_head *head;
 
        head = &h->ht[inet_sk(sk)->num & (RAW_HTABLE_SIZE - 1)];
 
        write_lock_bh(&h->lock);
        sk_add_node(sk, head);
-       sock_prot_inuse_add(sk->sk_prot, 1);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        write_unlock_bh(&h->lock);
 }
 EXPORT_SYMBOL_GPL(raw_hash_sk);
 
-void raw_unhash_sk(struct sock *sk, struct raw_hashinfo *h)
+void raw_unhash_sk(struct sock *sk)
 {
+       struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
+
        write_lock_bh(&h->lock);
        if (sk_del_node_init(sk))
-               sock_prot_inuse_add(sk->sk_prot, -1);
+               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        write_unlock_bh(&h->lock);
 }
 EXPORT_SYMBOL_GPL(raw_unhash_sk);
 
-static void raw_v4_hash(struct sock *sk)
-{
-       raw_hash_sk(sk, &raw_v4_hashinfo);
-}
-
-static void raw_v4_unhash(struct sock *sk)
-{
-       raw_unhash_sk(sk, &raw_v4_hashinfo);
-}
-
 static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
                unsigned short num, __be32 raddr, __be32 laddr, int dif)
 {
@@ -124,7 +115,7 @@ static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
        sk_for_each_from(sk, node) {
                struct inet_sock *inet = inet_sk(sk);
 
-               if (sk->sk_net == net && inet->num == num               &&
+               if (net_eq(sock_net(sk), net) && inet->num == num       &&
                    !(inet->daddr && inet->daddr != raddr)              &&
                    !(inet->rcv_saddr && inet->rcv_saddr != laddr)      &&
                    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
@@ -175,7 +166,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
        if (hlist_empty(head))
                goto out;
 
-       net = skb->dev->nd_net;
+       net = dev_net(skb->dev);
        sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
                             iph->saddr, iph->daddr,
                             skb->dev->ifindex);
@@ -283,7 +274,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
        raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
        if (raw_sk != NULL) {
                iph = (struct iphdr *)skb->data;
-               net = skb->dev->nd_net;
+               net = dev_net(skb->dev);
 
                while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
                                                iph->daddr, iph->saddr,
@@ -329,7 +320,6 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
                        unsigned int flags)
 {
        struct inet_sock *inet = inet_sk(sk);
-       int hh_len;
        struct iphdr *iph;
        struct sk_buff *skb;
        unsigned int iphlen;
@@ -343,13 +333,12 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
        if (flags&MSG_PROBE)
                goto out;
 
-       hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
-       skb = sock_alloc_send_skb(sk, length+hh_len+15,
-                                 flags&MSG_DONTWAIT, &err);
+       skb = sock_alloc_send_skb(sk,
+                                 length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
+                                 flags & MSG_DONTWAIT, &err);
        if (skb == NULL)
                goto error;
-       skb_reserve(skb, hh_len);
+       skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
 
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
@@ -506,7 +495,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        ipc.oif = sk->sk_bound_dev_if;
 
        if (msg->msg_controllen) {
-               err = ip_cmsg_send(msg, &ipc);
+               err = ip_cmsg_send(sock_net(sk), msg, &ipc);
                if (err)
                        goto out;
                if (ipc.opt)
@@ -560,7 +549,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                }
 
                security_sk_classify_flow(sk, &fl);
-               err = ip_route_output_flow(&init_net, &rt, &fl, sk, 1);
+               err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1);
        }
        if (err)
                goto done;
@@ -617,6 +606,14 @@ static void raw_close(struct sock *sk, long timeout)
        sk_common_release(sk);
 }
 
+static int raw_destroy(struct sock *sk)
+{
+       lock_sock(sk);
+       ip_flush_pending_frames(sk);
+       release_sock(sk);
+       return 0;
+}
+
 /* This gets rid of all the nasties in af_inet. -DaveM */
 static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
@@ -627,7 +624,7 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 
        if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
                goto out;
-       chk_addr_ret = inet_addr_type(sk->sk_net, addr->sin_addr.s_addr);
+       chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
        ret = -EADDRNOTAVAIL;
        if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
            chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
@@ -825,12 +822,11 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
        }
 }
 
-DEFINE_PROTO_INUSE(raw)
-
 struct proto raw_prot = {
        .name              = "RAW",
        .owner             = THIS_MODULE,
        .close             = raw_close,
+       .destroy           = raw_destroy,
        .connect           = ip4_datagram_connect,
        .disconnect        = udp_disconnect,
        .ioctl             = raw_ioctl,
@@ -841,14 +837,14 @@ struct proto raw_prot = {
        .recvmsg           = raw_recvmsg,
        .bind              = raw_bind,
        .backlog_rcv       = raw_rcv_skb,
-       .hash              = raw_v4_hash,
-       .unhash            = raw_v4_unhash,
+       .hash              = raw_hash_sk,
+       .unhash            = raw_unhash_sk,
        .obj_size          = sizeof(struct raw_sock),
+       .h.raw_hash        = &raw_v4_hashinfo,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_raw_setsockopt,
        .compat_getsockopt = compat_raw_getsockopt,
 #endif
-       REF_PROTO_INUSE(raw)
 };
 
 #ifdef CONFIG_PROC_FS
@@ -862,7 +858,7 @@ static struct sock *raw_get_first(struct seq_file *seq)
                struct hlist_node *node;
 
                sk_for_each(sk, node, &state->h->ht[state->bucket])
-                       if (sk->sk_net == state->p.net)
+                       if (sock_net(sk) == seq_file_net(seq))
                                goto found;
        }
        sk = NULL;
@@ -878,7 +874,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
                sk = sk_next(sk);
 try_again:
                ;
-       } while (sk && sk->sk_net != state->p.net);
+       } while (sk && sock_net(sk) != seq_file_net(seq));
 
        if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
                sk = sk_head(&state->h->ht[state->bucket]);