net/packet/af_packet.c
changeset 2 d1f6d8b6f81c
parent 0 aa628870c1d3
equal deleted inserted replaced
1:0056487c491e 2:d1f6d8b6f81c
    75 #include <linux/proc_fs.h>
    75 #include <linux/proc_fs.h>
    76 #include <linux/seq_file.h>
    76 #include <linux/seq_file.h>
    77 #include <linux/poll.h>
    77 #include <linux/poll.h>
    78 #include <linux/module.h>
    78 #include <linux/module.h>
    79 #include <linux/init.h>
    79 #include <linux/init.h>
       
    80 #include <linux/mutex.h>
    80 
    81 
    81 #ifdef CONFIG_INET
    82 #ifdef CONFIG_INET
    82 #include <net/inet_common.h>
    83 #include <net/inet_common.h>
    83 #endif
    84 #endif
    84 
    85 
   173 	unsigned int		frame_max;
   174 	unsigned int		frame_max;
   174 	int			copy_thresh;
   175 	int			copy_thresh;
   175 #endif
   176 #endif
   176 	struct packet_type	prot_hook;
   177 	struct packet_type	prot_hook;
   177 	spinlock_t		bind_lock;
   178 	spinlock_t		bind_lock;
       
   179 	struct mutex		pg_vec_lock;
   178 	unsigned int		running:1,	/* prot_hook is attached*/
   180 	unsigned int		running:1,	/* prot_hook is attached*/
   179 				auxdata:1,
   181 				auxdata:1,
   180 				origdev:1;
   182 				origdev:1;
   181 	int			ifindex;	/* bound device		*/
   183 	int			ifindex;	/* bound device		*/
   182 	__be16			num;
   184 	__be16			num;
   218 	frame_offset = position % po->frames_per_block;
   220 	frame_offset = position % po->frames_per_block;
   219 
   221 
   220 	h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
   222 	h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
   221 	switch (po->tp_version) {
   223 	switch (po->tp_version) {
   222 	case TPACKET_V1:
   224 	case TPACKET_V1:
   223 		if (status != h.h1->tp_status ? TP_STATUS_USER :
   225 		if (status != (h.h1->tp_status ? TP_STATUS_USER :
   224 						TP_STATUS_KERNEL)
   226 						TP_STATUS_KERNEL))
   225 			return NULL;
   227 			return NULL;
   226 		break;
   228 		break;
   227 	case TPACKET_V2:
   229 	case TPACKET_V2:
   228 		if (status != h.h2->tp_status ? TP_STATUS_USER :
   230 		if (status != (h.h2->tp_status ? TP_STATUS_USER :
   229 						TP_STATUS_KERNEL)
   231 						TP_STATUS_KERNEL))
   230 			return NULL;
   232 			return NULL;
   231 		break;
   233 		break;
   232 	}
   234 	}
   233 	return h.raw;
   235 	return h.raw;
   234 }
   236 }
   870 	net = sock_net(sk);
   872 	net = sock_net(sk);
   871 	po = pkt_sk(sk);
   873 	po = pkt_sk(sk);
   872 
   874 
   873 	write_lock_bh(&net->packet.sklist_lock);
   875 	write_lock_bh(&net->packet.sklist_lock);
   874 	sk_del_node_init(sk);
   876 	sk_del_node_init(sk);
       
   877 	sock_prot_inuse_add(net, sk->sk_prot, -1);
   875 	write_unlock_bh(&net->packet.sklist_lock);
   878 	write_unlock_bh(&net->packet.sklist_lock);
   876 
   879 
   877 	/*
   880 	/*
   878 	 *	Unhook packet receive handler.
   881 	 *	Unhook packet receive handler.
   879 	 */
   882 	 */
  1066 	/*
  1069 	/*
  1067 	 *	Attach a protocol block
  1070 	 *	Attach a protocol block
  1068 	 */
  1071 	 */
  1069 
  1072 
  1070 	spin_lock_init(&po->bind_lock);
  1073 	spin_lock_init(&po->bind_lock);
       
  1074 	mutex_init(&po->pg_vec_lock);
  1071 	po->prot_hook.func = packet_rcv;
  1075 	po->prot_hook.func = packet_rcv;
  1072 
  1076 
  1073 	if (sock->type == SOCK_PACKET)
  1077 	if (sock->type == SOCK_PACKET)
  1074 		po->prot_hook.func = packet_rcv_spkt;
  1078 		po->prot_hook.func = packet_rcv_spkt;
  1075 
  1079 
  1082 		po->running = 1;
  1086 		po->running = 1;
  1083 	}
  1087 	}
  1084 
  1088 
  1085 	write_lock_bh(&net->packet.sklist_lock);
  1089 	write_lock_bh(&net->packet.sklist_lock);
  1086 	sk_add_node(sk, &net->packet.sklist);
  1090 	sk_add_node(sk, &net->packet.sklist);
       
  1091 	sock_prot_inuse_add(net, &packet_proto, 1);
  1087 	write_unlock_bh(&net->packet.sklist_lock);
  1092 	write_unlock_bh(&net->packet.sklist_lock);
  1088 	return(0);
  1093 	return(0);
  1089 out:
  1094 out:
  1090 	return err;
  1095 	return err;
  1091 }
  1096 }
  1861 	spin_unlock(&po->bind_lock);
  1866 	spin_unlock(&po->bind_lock);
  1862 
  1867 
  1863 	synchronize_net();
  1868 	synchronize_net();
  1864 
  1869 
  1865 	err = -EBUSY;
  1870 	err = -EBUSY;
       
  1871 	mutex_lock(&po->pg_vec_lock);
  1866 	if (closing || atomic_read(&po->mapped) == 0) {
  1872 	if (closing || atomic_read(&po->mapped) == 0) {
  1867 		err = 0;
  1873 		err = 0;
  1868 #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
  1874 #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
  1869 
  1875 
  1870 		spin_lock_bh(&sk->sk_receive_queue.lock);
  1876 		spin_lock_bh(&sk->sk_receive_queue.lock);
  1882 		skb_queue_purge(&sk->sk_receive_queue);
  1888 		skb_queue_purge(&sk->sk_receive_queue);
  1883 #undef XC
  1889 #undef XC
  1884 		if (atomic_read(&po->mapped))
  1890 		if (atomic_read(&po->mapped))
  1885 			printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
  1891 			printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
  1886 	}
  1892 	}
       
  1893 	mutex_unlock(&po->pg_vec_lock);
  1887 
  1894 
  1888 	spin_lock(&po->bind_lock);
  1895 	spin_lock(&po->bind_lock);
  1889 	if (was_running && !po->running) {
  1896 	if (was_running && !po->running) {
  1890 		sock_hold(sk);
  1897 		sock_hold(sk);
  1891 		po->running = 1;
  1898 		po->running = 1;
  1914 	if (vma->vm_pgoff)
  1921 	if (vma->vm_pgoff)
  1915 		return -EINVAL;
  1922 		return -EINVAL;
  1916 
  1923 
  1917 	size = vma->vm_end - vma->vm_start;
  1924 	size = vma->vm_end - vma->vm_start;
  1918 
  1925 
  1919 	lock_sock(sk);
  1926 	mutex_lock(&po->pg_vec_lock);
  1920 	if (po->pg_vec == NULL)
  1927 	if (po->pg_vec == NULL)
  1921 		goto out;
  1928 		goto out;
  1922 	if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
  1929 	if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
  1923 		goto out;
  1930 		goto out;
  1924 
  1931 
  1937 	atomic_inc(&po->mapped);
  1944 	atomic_inc(&po->mapped);
  1938 	vma->vm_ops = &packet_mmap_ops;
  1945 	vma->vm_ops = &packet_mmap_ops;
  1939 	err = 0;
  1946 	err = 0;
  1940 
  1947 
  1941 out:
  1948 out:
  1942 	release_sock(sk);
  1949 	mutex_unlock(&po->pg_vec_lock);
  1943 	return err;
  1950 	return err;
  1944 }
  1951 }
  1945 #endif
  1952 #endif
  1946 
  1953 
  1947 
  1954