diff options
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r-- | net/core/skbuff.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index cd4ba8c6b609..f86bf69cfb8d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3082,22 +3082,32 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, | |||
3082 | if (sg && csum && (mss != GSO_BY_FRAGS)) { | 3082 | if (sg && csum && (mss != GSO_BY_FRAGS)) { |
3083 | if (!(features & NETIF_F_GSO_PARTIAL)) { | 3083 | if (!(features & NETIF_F_GSO_PARTIAL)) { |
3084 | struct sk_buff *iter; | 3084 | struct sk_buff *iter; |
3085 | unsigned int frag_len; | ||
3085 | 3086 | ||
3086 | if (!list_skb || | 3087 | if (!list_skb || |
3087 | !net_gso_ok(features, skb_shinfo(head_skb)->gso_type)) | 3088 | !net_gso_ok(features, skb_shinfo(head_skb)->gso_type)) |
3088 | goto normal; | 3089 | goto normal; |
3089 | 3090 | ||
3090 | /* Split the buffer at the frag_list pointer. | 3091 | /* If we get here then all the required |
3091 | * This is based on the assumption that all | 3092 | * GSO features except frag_list are supported. |
3092 | * buffers in the chain excluding the last | 3093 | * Try to split the SKB to multiple GSO SKBs |
3093 | * containing the same amount of data. | 3094 | * with no frag_list. |
3095 | * Currently we can do that only when the buffers don't | ||
3096 | * have a linear part and all the buffers except | ||
3097 | * the last are of the same length. | ||
3094 | */ | 3098 | */ |
3099 | frag_len = list_skb->len; | ||
3095 | skb_walk_frags(head_skb, iter) { | 3100 | skb_walk_frags(head_skb, iter) { |
3101 | if (frag_len != iter->len && iter->next) | ||
3102 | goto normal; | ||
3096 | if (skb_headlen(iter)) | 3103 | if (skb_headlen(iter)) |
3097 | goto normal; | 3104 | goto normal; |
3098 | 3105 | ||
3099 | len -= iter->len; | 3106 | len -= iter->len; |
3100 | } | 3107 | } |
3108 | |||
3109 | if (len != frag_len) | ||
3110 | goto normal; | ||
3101 | } | 3111 | } |
3102 | 3112 | ||
3103 | /* GSO partial only requires that we trim off any excess that | 3113 | /* GSO partial only requires that we trim off any excess that |
@@ -3694,6 +3704,15 @@ static void sock_rmem_free(struct sk_buff *skb) | |||
3694 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); | 3704 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); |
3695 | } | 3705 | } |
3696 | 3706 | ||
3707 | static void skb_set_err_queue(struct sk_buff *skb) | ||
3708 | { | ||
3709 | /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING. | ||
3710 | * So, it is safe to (mis)use it to mark skbs on the error queue. | ||
3711 | */ | ||
3712 | skb->pkt_type = PACKET_OUTGOING; | ||
3713 | BUILD_BUG_ON(PACKET_OUTGOING == 0); | ||
3714 | } | ||
3715 | |||
3697 | /* | 3716 | /* |
3698 | * Note: We dont mem charge error packets (no sk_forward_alloc changes) | 3717 | * Note: We dont mem charge error packets (no sk_forward_alloc changes) |
3699 | */ | 3718 | */ |
@@ -3707,6 +3726,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) | |||
3707 | skb->sk = sk; | 3726 | skb->sk = sk; |
3708 | skb->destructor = sock_rmem_free; | 3727 | skb->destructor = sock_rmem_free; |
3709 | atomic_add(skb->truesize, &sk->sk_rmem_alloc); | 3728 | atomic_add(skb->truesize, &sk->sk_rmem_alloc); |
3729 | skb_set_err_queue(skb); | ||
3710 | 3730 | ||
3711 | /* before exiting rcu section, make sure dst is refcounted */ | 3731 | /* before exiting rcu section, make sure dst is refcounted */ |
3712 | skb_dst_force(skb); | 3732 | skb_dst_force(skb); |
@@ -3783,16 +3803,21 @@ EXPORT_SYMBOL(skb_clone_sk); | |||
3783 | 3803 | ||
3784 | static void __skb_complete_tx_timestamp(struct sk_buff *skb, | 3804 | static void __skb_complete_tx_timestamp(struct sk_buff *skb, |
3785 | struct sock *sk, | 3805 | struct sock *sk, |
3786 | int tstype) | 3806 | int tstype, |
3807 | bool opt_stats) | ||
3787 | { | 3808 | { |
3788 | struct sock_exterr_skb *serr; | 3809 | struct sock_exterr_skb *serr; |
3789 | int err; | 3810 | int err; |
3790 | 3811 | ||
3812 | BUILD_BUG_ON(sizeof(struct sock_exterr_skb) > sizeof(skb->cb)); | ||
3813 | |||
3791 | serr = SKB_EXT_ERR(skb); | 3814 | serr = SKB_EXT_ERR(skb); |
3792 | memset(serr, 0, sizeof(*serr)); | 3815 | memset(serr, 0, sizeof(*serr)); |
3793 | serr->ee.ee_errno = ENOMSG; | 3816 | serr->ee.ee_errno = ENOMSG; |
3794 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; | 3817 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; |
3795 | serr->ee.ee_info = tstype; | 3818 | serr->ee.ee_info = tstype; |
3819 | serr->opt_stats = opt_stats; | ||
3820 | serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; | ||
3796 | if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { | 3821 | if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { |
3797 | serr->ee.ee_data = skb_shinfo(skb)->tskey; | 3822 | serr->ee.ee_data = skb_shinfo(skb)->tskey; |
3798 | if (sk->sk_protocol == IPPROTO_TCP && | 3823 | if (sk->sk_protocol == IPPROTO_TCP && |
@@ -3833,7 +3858,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
3833 | */ | 3858 | */ |
3834 | if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { | 3859 | if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { |
3835 | *skb_hwtstamps(skb) = *hwtstamps; | 3860 | *skb_hwtstamps(skb) = *hwtstamps; |
3836 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); | 3861 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false); |
3837 | sock_put(sk); | 3862 | sock_put(sk); |
3838 | } | 3863 | } |
3839 | } | 3864 | } |
@@ -3844,7 +3869,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3844 | struct sock *sk, int tstype) | 3869 | struct sock *sk, int tstype) |
3845 | { | 3870 | { |
3846 | struct sk_buff *skb; | 3871 | struct sk_buff *skb; |
3847 | bool tsonly; | 3872 | bool tsonly, opt_stats = false; |
3848 | 3873 | ||
3849 | if (!sk) | 3874 | if (!sk) |
3850 | return; | 3875 | return; |
@@ -3857,9 +3882,10 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3857 | #ifdef CONFIG_INET | 3882 | #ifdef CONFIG_INET |
3858 | if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) && | 3883 | if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) && |
3859 | sk->sk_protocol == IPPROTO_TCP && | 3884 | sk->sk_protocol == IPPROTO_TCP && |
3860 | sk->sk_type == SOCK_STREAM) | 3885 | sk->sk_type == SOCK_STREAM) { |
3861 | skb = tcp_get_timestamping_opt_stats(sk); | 3886 | skb = tcp_get_timestamping_opt_stats(sk); |
3862 | else | 3887 | opt_stats = true; |
3888 | } else | ||
3863 | #endif | 3889 | #endif |
3864 | skb = alloc_skb(0, GFP_ATOMIC); | 3890 | skb = alloc_skb(0, GFP_ATOMIC); |
3865 | } else { | 3891 | } else { |
@@ -3878,7 +3904,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3878 | else | 3904 | else |
3879 | skb->tstamp = ktime_get_real(); | 3905 | skb->tstamp = ktime_get_real(); |
3880 | 3906 | ||
3881 | __skb_complete_tx_timestamp(skb, sk, tstype); | 3907 | __skb_complete_tx_timestamp(skb, sk, tstype, opt_stats); |
3882 | } | 3908 | } |
3883 | EXPORT_SYMBOL_GPL(__skb_tstamp_tx); | 3909 | EXPORT_SYMBOL_GPL(__skb_tstamp_tx); |
3884 | 3910 | ||