@@ -2494,14 +2494,13 @@ static int packet_snd_vnet_gso(struct sk_buff *skb,
2494
2494
}
2495
2495
2496
2496
static int tpacket_fill_skb (struct packet_sock * po , struct sk_buff * skb ,
2497
- void * frame , struct net_device * dev , int size_max ,
2497
+ void * frame , struct net_device * dev , void * data , int tp_len ,
2498
2498
__be16 proto , unsigned char * addr , int hlen )
2499
2499
{
2500
2500
union tpacket_uhdr ph ;
2501
- int to_write , offset , len , tp_len , nr_frags , len_max ;
2501
+ int to_write , offset , len , nr_frags , len_max ;
2502
2502
struct socket * sock = po -> sk .sk_socket ;
2503
2503
struct page * page ;
2504
- void * data ;
2505
2504
int err ;
2506
2505
2507
2506
ph .raw = frame ;
@@ -2513,51 +2512,9 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2513
2512
sock_tx_timestamp (& po -> sk , & skb_shinfo (skb )-> tx_flags );
2514
2513
skb_shinfo (skb )-> destructor_arg = ph .raw ;
2515
2514
2516
- switch (po -> tp_version ) {
2517
- case TPACKET_V2 :
2518
- tp_len = ph .h2 -> tp_len ;
2519
- break ;
2520
- default :
2521
- tp_len = ph .h1 -> tp_len ;
2522
- break ;
2523
- }
2524
- if (unlikely (tp_len > size_max )) {
2525
- pr_err ("packet size is too long (%d > %d)\n" , tp_len , size_max );
2526
- return - EMSGSIZE ;
2527
- }
2528
-
2529
2515
skb_reserve (skb , hlen );
2530
2516
skb_reset_network_header (skb );
2531
2517
2532
- if (unlikely (po -> tp_tx_has_off )) {
2533
- int off_min , off_max , off ;
2534
- off_min = po -> tp_hdrlen - sizeof (struct sockaddr_ll );
2535
- off_max = po -> tx_ring .frame_size - tp_len ;
2536
- if (sock -> type == SOCK_DGRAM ) {
2537
- switch (po -> tp_version ) {
2538
- case TPACKET_V2 :
2539
- off = ph .h2 -> tp_net ;
2540
- break ;
2541
- default :
2542
- off = ph .h1 -> tp_net ;
2543
- break ;
2544
- }
2545
- } else {
2546
- switch (po -> tp_version ) {
2547
- case TPACKET_V2 :
2548
- off = ph .h2 -> tp_mac ;
2549
- break ;
2550
- default :
2551
- off = ph .h1 -> tp_mac ;
2552
- break ;
2553
- }
2554
- }
2555
- if (unlikely ((off < off_min ) || (off_max < off )))
2556
- return - EINVAL ;
2557
- data = ph .raw + off ;
2558
- } else {
2559
- data = ph .raw + po -> tp_hdrlen - sizeof (struct sockaddr_ll );
2560
- }
2561
2518
to_write = tp_len ;
2562
2519
2563
2520
if (sock -> type == SOCK_DGRAM ) {
@@ -2615,6 +2572,61 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2615
2572
return tp_len ;
2616
2573
}
2617
2574
2575
+ static int tpacket_parse_header (struct packet_sock * po , void * frame ,
2576
+ int size_max , void * * data )
2577
+ {
2578
+ union tpacket_uhdr ph ;
2579
+ int tp_len , off ;
2580
+
2581
+ ph .raw = frame ;
2582
+
2583
+ switch (po -> tp_version ) {
2584
+ case TPACKET_V2 :
2585
+ tp_len = ph .h2 -> tp_len ;
2586
+ break ;
2587
+ default :
2588
+ tp_len = ph .h1 -> tp_len ;
2589
+ break ;
2590
+ }
2591
+ if (unlikely (tp_len > size_max )) {
2592
+ pr_err ("packet size is too long (%d > %d)\n" , tp_len , size_max );
2593
+ return - EMSGSIZE ;
2594
+ }
2595
+
2596
+ if (unlikely (po -> tp_tx_has_off )) {
2597
+ int off_min , off_max ;
2598
+
2599
+ off_min = po -> tp_hdrlen - sizeof (struct sockaddr_ll );
2600
+ off_max = po -> tx_ring .frame_size - tp_len ;
2601
+ if (po -> sk .sk_type == SOCK_DGRAM ) {
2602
+ switch (po -> tp_version ) {
2603
+ case TPACKET_V2 :
2604
+ off = ph .h2 -> tp_net ;
2605
+ break ;
2606
+ default :
2607
+ off = ph .h1 -> tp_net ;
2608
+ break ;
2609
+ }
2610
+ } else {
2611
+ switch (po -> tp_version ) {
2612
+ case TPACKET_V2 :
2613
+ off = ph .h2 -> tp_mac ;
2614
+ break ;
2615
+ default :
2616
+ off = ph .h1 -> tp_mac ;
2617
+ break ;
2618
+ }
2619
+ }
2620
+ if (unlikely ((off < off_min ) || (off_max < off )))
2621
+ return - EINVAL ;
2622
+ } else {
2623
+ off = po -> tp_hdrlen - sizeof (struct sockaddr_ll );
2624
+ }
2625
+
2626
+ * data = frame + off ;
2627
+ return tp_len ;
2628
+ }
2629
+
2618
2630
static int tpacket_snd (struct packet_sock * po , struct msghdr * msg )
2619
2631
{
2620
2632
struct sk_buff * skb ;
@@ -2626,6 +2638,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2626
2638
bool need_wait = !(msg -> msg_flags & MSG_DONTWAIT );
2627
2639
int tp_len , size_max ;
2628
2640
unsigned char * addr ;
2641
+ void * data ;
2629
2642
int len_sum = 0 ;
2630
2643
int status = TP_STATUS_AVAILABLE ;
2631
2644
int hlen , tlen ;
@@ -2673,6 +2686,11 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2673
2686
continue ;
2674
2687
}
2675
2688
2689
+ skb = NULL ;
2690
+ tp_len = tpacket_parse_header (po , ph , size_max , & data );
2691
+ if (tp_len < 0 )
2692
+ goto tpacket_error ;
2693
+
2676
2694
status = TP_STATUS_SEND_REQUEST ;
2677
2695
hlen = LL_RESERVED_SPACE (dev );
2678
2696
tlen = dev -> needed_tailroom ;
@@ -2686,14 +2704,15 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2686
2704
err = len_sum ;
2687
2705
goto out_status ;
2688
2706
}
2689
- tp_len = tpacket_fill_skb (po , skb , ph , dev , size_max , proto ,
2707
+ tp_len = tpacket_fill_skb (po , skb , ph , dev , data , tp_len , proto ,
2690
2708
addr , hlen );
2691
2709
if (likely (tp_len >= 0 ) &&
2692
2710
tp_len > dev -> mtu + reserve &&
2693
2711
!packet_extra_vlan_len_allowed (dev , skb ))
2694
2712
tp_len = - EMSGSIZE ;
2695
2713
2696
2714
if (unlikely (tp_len < 0 )) {
2715
+ tpacket_error :
2697
2716
if (po -> tp_loss ) {
2698
2717
__packet_set_status (po , ph ,
2699
2718
TP_STATUS_AVAILABLE );
0 commit comments