af_packet.c (93cd6fa6806cb3455e8231578840afb031606352) | af_packet.c (cbbd26b8b1a6af9c02e2b6523e12bd50cc765059) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * PACKET - implements raw packet sockets. 7 * 8 * Authors: Ross Biro --- 2418 unchanged lines hidden (view full) --- 2427 2428 vnet_hdr->gso_type = gso_type; /* changes type, temporary storage */ 2429 return 0; 2430} 2431 2432static int packet_snd_vnet_parse(struct msghdr *msg, size_t *len, 2433 struct virtio_net_hdr *vnet_hdr) 2434{ | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * PACKET - implements raw packet sockets. 7 * 8 * Authors: Ross Biro --- 2418 unchanged lines hidden (view full) --- 2427 2428 vnet_hdr->gso_type = gso_type; /* changes type, temporary storage */ 2429 return 0; 2430} 2431 2432static int packet_snd_vnet_parse(struct msghdr *msg, size_t *len, 2433 struct virtio_net_hdr *vnet_hdr) 2434{ |
2435 int n; 2436 | |
2437 if (*len < sizeof(*vnet_hdr)) 2438 return -EINVAL; 2439 *len -= sizeof(*vnet_hdr); 2440 | 2435 if (*len < sizeof(*vnet_hdr)) 2436 return -EINVAL; 2437 *len -= sizeof(*vnet_hdr); 2438 |
2441 n = copy_from_iter(vnet_hdr, sizeof(*vnet_hdr), &msg->msg_iter); 2442 if (n != sizeof(*vnet_hdr)) | 2439 if (!copy_from_iter_full(vnet_hdr, sizeof(*vnet_hdr), &msg->msg_iter)) |
2443 return -EFAULT; 2444 2445 return __packet_snd_vnet_parse(vnet_hdr, *len); 2446} 2447 2448static int packet_snd_vnet_gso(struct sk_buff *skb, 2449 struct virtio_net_hdr *vnet_hdr) 2450{ --- 1192 unchanged lines hidden (view full) --- 3643 return 0; 3644 } 3645 case PACKET_VERSION: 3646 { 3647 int val; 3648 3649 if (optlen != sizeof(val)) 3650 return -EINVAL; | 2440 return -EFAULT; 2441 2442 return __packet_snd_vnet_parse(vnet_hdr, *len); 2443} 2444 2445static int packet_snd_vnet_gso(struct sk_buff *skb, 2446 struct virtio_net_hdr *vnet_hdr) 2447{ --- 1192 unchanged lines hidden (view full) --- 3640 return 0; 3641 } 3642 case PACKET_VERSION: 3643 { 3644 int val; 3645 3646 if (optlen != sizeof(val)) 3647 return -EINVAL; |
3648 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) 3649 return -EBUSY; |
|
3651 if (copy_from_user(&val, optval, sizeof(val))) 3652 return -EFAULT; 3653 switch (val) { 3654 case TPACKET_V1: 3655 case TPACKET_V2: 3656 case TPACKET_V3: | 3650 if (copy_from_user(&val, optval, sizeof(val))) 3651 return -EFAULT; 3652 switch (val) { 3653 case TPACKET_V1: 3654 case TPACKET_V2: 3655 case TPACKET_V3: |
3657 break; | 3656 po->tp_version = val; 3657 return 0; |
3658 default: 3659 return -EINVAL; 3660 } | 3658 default: 3659 return -EINVAL; 3660 } |
3661 lock_sock(sk); 3662 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { 3663 ret = -EBUSY; 3664 } else { 3665 po->tp_version = val; 3666 ret = 0; 3667 } 3668 release_sock(sk); 3669 return ret; | |
3670 } 3671 case PACKET_RESERVE: 3672 { 3673 unsigned int val; 3674 3675 if (optlen != sizeof(val)) 3676 return -EINVAL; 3677 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) --- 487 unchanged lines hidden (view full) --- 4165 int was_running, order = 0; 4166 struct packet_ring_buffer *rb; 4167 struct sk_buff_head *rb_queue; 4168 __be16 num; 4169 int err = -EINVAL; 4170 /* Added to avoid minimal code churn */ 4171 struct tpacket_req *req = &req_u->req; 4172 | 3661 } 3662 case PACKET_RESERVE: 3663 { 3664 unsigned int val; 3665 3666 if (optlen != sizeof(val)) 3667 return -EINVAL; 3668 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) --- 487 unchanged lines hidden (view full) --- 4156 int was_running, order = 0; 4157 struct packet_ring_buffer *rb; 4158 struct sk_buff_head *rb_queue; 4159 __be16 num; 4160 int err = -EINVAL; 4161 /* Added to avoid minimal code churn */ 4162 struct tpacket_req *req = &req_u->req; 4163 |
4173 lock_sock(sk); | |
4174 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ 4175 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { 4176 net_warn_ratelimited("Tx-ring is not supported.\n"); 4177 goto out; 4178 } 4179 4180 rb = tx_ring ? &po->tx_ring : &po->rx_ring; 4181 rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue; --- 65 unchanged lines hidden (view full) --- 4247 } 4248 /* Done */ 4249 else { 4250 err = -EINVAL; 4251 if (unlikely(req->tp_frame_nr)) 4252 goto out; 4253 } 4254 | 4164 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ 4165 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { 4166 net_warn_ratelimited("Tx-ring is not supported.\n"); 4167 goto out; 4168 } 4169 4170 rb = tx_ring ? &po->tx_ring : &po->rx_ring; 4171 rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue; --- 65 unchanged lines hidden (view full) --- 4237 } 4238 /* Done */ 4239 else { 4240 err = -EINVAL; 4241 if (unlikely(req->tp_frame_nr)) 4242 goto out; 4243 } 4244 |
4245 lock_sock(sk); |
|
4255 4256 /* Detach socket from network */ 4257 spin_lock(&po->bind_lock); 4258 was_running = po->running; 4259 num = po->num; 4260 if (was_running) { 4261 po->num = 0; 4262 __unregister_prot_hook(sk, false); --- 32 unchanged lines hidden (view full) --- 4295 register_prot_hook(sk); 4296 } 4297 spin_unlock(&po->bind_lock); 4298 if (closing && (po->tp_version > TPACKET_V2)) { 4299 /* Because we don't support block-based V3 on tx-ring */ 4300 if (!tx_ring) 4301 prb_shutdown_retire_blk_timer(po, rb_queue); 4302 } | 4246 4247 /* Detach socket from network */ 4248 spin_lock(&po->bind_lock); 4249 was_running = po->running; 4250 num = po->num; 4251 if (was_running) { 4252 po->num = 0; 4253 __unregister_prot_hook(sk, false); --- 32 unchanged lines hidden (view full) --- 4286 register_prot_hook(sk); 4287 } 4288 spin_unlock(&po->bind_lock); 4289 if (closing && (po->tp_version > TPACKET_V2)) { 4290 /* Because we don't support block-based V3 on tx-ring */ 4291 if (!tx_ring) 4292 prb_shutdown_retire_blk_timer(po, rb_queue); 4293 } |
4294 release_sock(sk); |
|
4303 4304 if (pg_vec) 4305 free_pg_vec(pg_vec, order, req->tp_block_nr); 4306out: | 4295 4296 if (pg_vec) 4297 free_pg_vec(pg_vec, order, req->tp_block_nr); 4298out: |
4307 release_sock(sk); | |
4308 return err; 4309} 4310 4311static int packet_mmap(struct file *file, struct socket *sock, 4312 struct vm_area_struct *vma) 4313{ 4314 struct sock *sk = sock->sk; 4315 struct packet_sock *po = pkt_sk(sk); --- 230 unchanged lines hidden --- | 4299 return err; 4300} 4301 4302static int packet_mmap(struct file *file, struct socket *sock, 4303 struct vm_area_struct *vma) 4304{ 4305 struct sock *sk = sock->sk; 4306 struct packet_sock *po = pkt_sk(sk); --- 230 unchanged lines hidden --- |