vserver 2.0 rc7
[linux-2.6.git] / net / packet / af_packet.c
index a996d9c..0269616 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Alan Cox, <gw4pts@gw4pts.ampr.org>
  *
@@ -170,8 +170,9 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
 
 static void packet_flush_mclist(struct sock *sk);
 
-struct packet_opt
-{
+struct packet_sock {
+       /* struct sock has to be the first member of packet_sock */
+       struct sock             sk;
        struct tpacket_stats    stats;
 #ifdef CONFIG_PACKET_MMAP
        char *                  *pg_vec;
@@ -199,7 +200,7 @@ struct packet_opt
 
 #ifdef CONFIG_PACKET_MMAP
 
-static inline char *packet_lookup_frame(struct packet_opt *po, unsigned int position)
+static inline char *packet_lookup_frame(struct packet_sock *po, unsigned int position)
 {
        unsigned int pg_vec_pos, frame_offset;
        char *frame;
@@ -213,7 +214,10 @@ static inline char *packet_lookup_frame(struct packet_opt *po, unsigned int posi
 }
 #endif
 
-#define pkt_sk(__sk) ((struct packet_opt *)(__sk)->sk_protinfo)
+static inline struct packet_sock *pkt_sk(struct sock *sk)
+{
+       return (struct packet_sock *)sk;
+}
 
 static void packet_sock_destruct(struct sock *sk)
 {
@@ -225,8 +229,6 @@ static void packet_sock_destruct(struct sock *sk)
                return;
        }
 
-       if (pkt_sk(sk))
-               kfree(pkt_sk(sk));
        atomic_dec(&packet_socks_nr);
 #ifdef PACKET_REFCNT_DEBUG
        printk(KERN_DEBUG "PACKET socket %p is free, %d are alive\n", sk, atomic_read(&packet_socks_nr));
@@ -440,7 +442,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,  struct packe
 {
        struct sock *sk;
        struct sockaddr_ll *sll;
-       struct packet_opt *po;
+       struct packet_sock *po;
        u8 * skb_head = skb->data;
        int skb_len = skb->len;
        unsigned snaplen;
@@ -541,7 +543,7 @@ drop:
 static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt)
 {
        struct sock *sk;
-       struct packet_opt *po;
+       struct packet_sock *po;
        struct sockaddr_ll *sll;
        struct tpacket_hdr *h;
        u8 * skb_head = skb->data;
@@ -699,7 +701,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
         */
         
        if (saddr == NULL) {
-               struct packet_opt *po = pkt_sk(sk);
+               struct packet_sock *po = pkt_sk(sk);
 
                ifindex = po->ifindex;
                proto   = po->num;
@@ -786,7 +788,7 @@ out:
 static int packet_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
-       struct packet_opt *po;
+       struct packet_sock *po;
 
        if (!sk)
                return 0;
@@ -844,7 +846,7 @@ static int packet_release(struct socket *sock)
 
 static int packet_do_bind(struct sock *sk, struct net_device *dev, int protocol)
 {
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        /*
         *      Detach an existing hook if present.
         */
@@ -953,6 +955,11 @@ out:
        return err;
 }
 
+static struct proto packet_proto = {
+       .name     = "PACKET",
+       .owner    = THIS_MODULE,
+       .obj_size = sizeof(struct packet_sock),
+};
 
 /*
  *     Create a packet of type SOCK_PACKET. 
@@ -961,7 +968,7 @@ out:
 static int packet_create(struct socket *sock, int protocol)
 {
        struct sock *sk;
-       struct packet_opt *po;
+       struct packet_sock *po;
        int err;
 
        if (!capable(CAP_NET_RAW))
@@ -976,7 +983,7 @@ static int packet_create(struct socket *sock, int protocol)
        sock->state = SS_UNCONNECTED;
 
        err = -ENOBUFS;
-       sk = sk_alloc(PF_PACKET, GFP_KERNEL, 1, NULL);
+       sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
        if (sk == NULL)
                goto out;
 
@@ -985,13 +992,9 @@ static int packet_create(struct socket *sock, int protocol)
        if (sock->type == SOCK_PACKET)
                sock->ops = &packet_ops_spkt;
 #endif
-       sock_init_data(sock,sk);
-       sk_set_owner(sk, THIS_MODULE);
+       sock_init_data(sock, sk);
 
-       po = sk->sk_protinfo = kmalloc(sizeof(*po), GFP_KERNEL);
-       if (!po)
-               goto out_free;
-       memset(po, 0, sizeof(*po));
+       po = pkt_sk(sk);
        sk->sk_family = PF_PACKET;
        po->num = protocol;
 
@@ -1021,9 +1024,6 @@ static int packet_create(struct socket *sock, int protocol)
        sk_add_node(sk, &packet_sklist);
        write_unlock_bh(&packet_sklist_lock);
        return(0);
-
-out_free:
-       sk_free(sk);
 out:
        return err;
 }
@@ -1141,7 +1141,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
 {
        struct net_device *dev;
        struct sock *sk = sock->sk;
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        struct sockaddr_ll *sll = (struct sockaddr_ll*)uaddr;
 
        if (peer)
@@ -1195,7 +1195,7 @@ static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, i
 
 static int packet_mc_add(struct sock *sk, struct packet_mreq *mreq)
 {
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        struct packet_mclist *ml, *i;
        struct net_device *dev;
        int err;
@@ -1274,7 +1274,7 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq *mreq)
 
 static void packet_flush_mclist(struct sock *sk)
 {
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        struct packet_mclist *ml;
 
        if (!po->mclist)
@@ -1355,7 +1355,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
 {
        int len;
        struct sock *sk = sock->sk;
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
 
        if (level != SOL_PACKET)
                return -ENOPROTOOPT;
@@ -1401,7 +1401,7 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
 
        read_lock(&packet_sklist_lock);
        sk_for_each(sk, node, &packet_sklist) {
-               struct packet_opt *po = pkt_sk(sk);
+               struct packet_sock *po = pkt_sk(sk);
 
                switch (msg) {
                case NETDEV_UNREGISTER:
@@ -1504,7 +1504,7 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
                                poll_table *wait)
 {
        struct sock *sk = sock->sk;
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        unsigned int mask = datagram_poll(file, sock, wait);
 
        spin_lock_bh(&sk->sk_receive_queue.lock);
@@ -1579,7 +1579,7 @@ static void free_pg_vec(char **pg_vec, unsigned order, unsigned len)
 static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing)
 {
        char **pg_vec = NULL;
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        int was_running, num, order = 0;
        int err = 0;
        
@@ -1709,7 +1709,7 @@ out:
 static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma)
 {
        struct sock *sk = sock->sk;
-       struct packet_opt *po = pkt_sk(sk);
+       struct packet_sock *po = pkt_sk(sk);
        unsigned long size;
        unsigned long start;
        int err = -EINVAL;
@@ -1839,7 +1839,7 @@ static int packet_seq_show(struct seq_file *seq, void *v)
                seq_puts(seq, "sk       RefCnt Type Proto  Iface R Rmem   User   Inode\n");
        else {
                struct sock *s = v;
-               const struct packet_opt *po = pkt_sk(s);
+               const struct packet_sock *po = pkt_sk(s);
 
                seq_printf(seq,
                           "%p %-6d %-4d %04x   %-5d %1d %-6u %-6u %-6lu\n",
@@ -1884,16 +1884,21 @@ static void __exit packet_exit(void)
        proc_net_remove("packet");
        unregister_netdevice_notifier(&packet_netdev_notifier);
        sock_unregister(PF_PACKET);
-       return;
+       proto_unregister(&packet_proto);
 }
 
 static int __init packet_init(void)
 {
+       int rc = proto_register(&packet_proto, 0);
+
+       if (rc != 0)
+               goto out;
+
        sock_register(&packet_family_ops);
        register_netdevice_notifier(&packet_netdev_notifier);
        proc_net_fops_create("packet", 0, &packet_seq_fops);
-
-       return 0;
+out:
+       return rc;
 }
 
 module_init(packet_init);