equal
deleted
inserted
replaced
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 |