@@ -2495,7 +2495,7 @@ static int packet_snd_vnet_gso(struct sk_buff *skb,
2495
2495
2496
2496
static int tpacket_fill_skb (struct packet_sock * po , struct sk_buff * skb ,
2497
2497
void * frame , struct net_device * dev , void * data , int tp_len ,
2498
- __be16 proto , unsigned char * addr , int hlen )
2498
+ __be16 proto , unsigned char * addr , int hlen , int copylen )
2499
2499
{
2500
2500
union tpacket_uhdr ph ;
2501
2501
int to_write , offset , len , nr_frags , len_max ;
@@ -2522,20 +2522,17 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2522
2522
NULL , tp_len );
2523
2523
if (unlikely (err < 0 ))
2524
2524
return - EINVAL ;
2525
- } else if (dev -> hard_header_len ) {
2526
- if (ll_header_truncated (dev , tp_len ))
2527
- return - EINVAL ;
2528
-
2525
+ } else if (copylen ) {
2529
2526
skb_push (skb , dev -> hard_header_len );
2530
- err = skb_store_bits (skb , 0 , data ,
2531
- dev -> hard_header_len );
2527
+ skb_put (skb , copylen - dev -> hard_header_len );
2528
+ err = skb_store_bits ( skb , 0 , data , copylen );
2532
2529
if (unlikely (err ))
2533
2530
return err ;
2534
2531
if (!skb -> protocol )
2535
2532
tpacket_set_protocol (dev , skb );
2536
2533
2537
- data += dev -> hard_header_len ;
2538
- to_write -= dev -> hard_header_len ;
2534
+ data += copylen ;
2535
+ to_write -= copylen ;
2539
2536
}
2540
2537
2541
2538
offset = offset_in_page (data );
@@ -2631,6 +2628,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2631
2628
{
2632
2629
struct sk_buff * skb ;
2633
2630
struct net_device * dev ;
2631
+ struct virtio_net_hdr * vnet_hdr = NULL ;
2634
2632
__be16 proto ;
2635
2633
int err , reserve = 0 ;
2636
2634
void * ph ;
@@ -2641,7 +2639,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2641
2639
void * data ;
2642
2640
int len_sum = 0 ;
2643
2641
int status = TP_STATUS_AVAILABLE ;
2644
- int hlen , tlen ;
2642
+ int hlen , tlen , copylen = 0 ;
2645
2643
2646
2644
mutex_lock (& po -> pg_vec_lock );
2647
2645
@@ -2674,7 +2672,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2674
2672
size_max = po -> tx_ring .frame_size
2675
2673
- (po -> tp_hdrlen - sizeof (struct sockaddr_ll ));
2676
2674
2677
- if (size_max > dev -> mtu + reserve + VLAN_HLEN )
2675
+ if (( size_max > dev -> mtu + reserve + VLAN_HLEN ) && ! po -> has_vnet_hdr )
2678
2676
size_max = dev -> mtu + reserve + VLAN_HLEN ;
2679
2677
2680
2678
do {
@@ -2694,8 +2692,28 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2694
2692
status = TP_STATUS_SEND_REQUEST ;
2695
2693
hlen = LL_RESERVED_SPACE (dev );
2696
2694
tlen = dev -> needed_tailroom ;
2695
+ if (po -> has_vnet_hdr ) {
2696
+ vnet_hdr = data ;
2697
+ data += sizeof (* vnet_hdr );
2698
+ tp_len -= sizeof (* vnet_hdr );
2699
+ if (tp_len < 0 ||
2700
+ __packet_snd_vnet_parse (vnet_hdr , tp_len )) {
2701
+ tp_len = - EINVAL ;
2702
+ goto tpacket_error ;
2703
+ }
2704
+ copylen = __virtio16_to_cpu (vio_le (),
2705
+ vnet_hdr -> hdr_len );
2706
+ }
2707
+ if (dev -> hard_header_len ) {
2708
+ if (ll_header_truncated (dev , tp_len )) {
2709
+ tp_len = - EINVAL ;
2710
+ goto tpacket_error ;
2711
+ }
2712
+ copylen = max_t (int , copylen , dev -> hard_header_len );
2713
+ }
2697
2714
skb = sock_alloc_send_skb (& po -> sk ,
2698
- hlen + tlen + sizeof (struct sockaddr_ll ),
2715
+ hlen + tlen + sizeof (struct sockaddr_ll ) +
2716
+ (copylen - dev -> hard_header_len ),
2699
2717
!need_wait , & err );
2700
2718
2701
2719
if (unlikely (skb == NULL )) {
@@ -2705,9 +2723,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2705
2723
goto out_status ;
2706
2724
}
2707
2725
tp_len = tpacket_fill_skb (po , skb , ph , dev , data , tp_len , proto ,
2708
- addr , hlen );
2726
+ addr , hlen , copylen );
2709
2727
if (likely (tp_len >= 0 ) &&
2710
2728
tp_len > dev -> mtu + reserve &&
2729
+ !po -> has_vnet_hdr &&
2711
2730
!packet_extra_vlan_len_allowed (dev , skb ))
2712
2731
tp_len = - EMSGSIZE ;
2713
2732
@@ -2726,6 +2745,11 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2726
2745
}
2727
2746
}
2728
2747
2748
+ if (po -> has_vnet_hdr && packet_snd_vnet_gso (skb , vnet_hdr )) {
2749
+ tp_len = - EINVAL ;
2750
+ goto tpacket_error ;
2751
+ }
2752
+
2729
2753
packet_pick_tx_queue (dev , skb );
2730
2754
2731
2755
skb -> destructor = tpacket_destruct_skb ;
@@ -3616,9 +3640,6 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
3616
3640
}
3617
3641
if (optlen < len )
3618
3642
return - EINVAL ;
3619
- if (pkt_sk (sk )-> has_vnet_hdr &&
3620
- optname == PACKET_TX_RING )
3621
- return - EINVAL ;
3622
3643
if (copy_from_user (& req_u .req , optval , len ))
3623
3644
return - EFAULT ;
3624
3645
return packet_set_ring (sk , & req_u , 0 ,
0 commit comments