@@ -2087,6 +2087,10 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
2087
2087
u32 off = skb_mac_header_len (skb );
2088
2088
int ret ;
2089
2089
2090
+ /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2091
+ if (skb_is_gso (skb ) && unlikely (skb_is_gso_sctp (skb )))
2092
+ return - ENOTSUPP ;
2093
+
2090
2094
ret = skb_cow (skb , len_diff );
2091
2095
if (unlikely (ret < 0 ))
2092
2096
return ret ;
@@ -2096,19 +2100,21 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
2096
2100
return ret ;
2097
2101
2098
2102
if (skb_is_gso (skb )) {
2103
+ struct skb_shared_info * shinfo = skb_shinfo (skb );
2104
+
2099
2105
/* SKB_GSO_TCPV4 needs to be changed into
2100
2106
* SKB_GSO_TCPV6.
2101
2107
*/
2102
- if (skb_shinfo ( skb ) -> gso_type & SKB_GSO_TCPV4 ) {
2103
- skb_shinfo ( skb ) -> gso_type &= ~SKB_GSO_TCPV4 ;
2104
- skb_shinfo ( skb ) -> gso_type |= SKB_GSO_TCPV6 ;
2108
+ if (shinfo -> gso_type & SKB_GSO_TCPV4 ) {
2109
+ shinfo -> gso_type &= ~SKB_GSO_TCPV4 ;
2110
+ shinfo -> gso_type |= SKB_GSO_TCPV6 ;
2105
2111
}
2106
2112
2107
2113
/* Due to IPv6 header, MSS needs to be downgraded. */
2108
- skb_shinfo ( skb ) -> gso_size -= len_diff ;
2114
+ skb_decrease_gso_size ( shinfo , len_diff ) ;
2109
2115
/* Header must be checked, and gso_segs recomputed. */
2110
- skb_shinfo ( skb ) -> gso_type |= SKB_GSO_DODGY ;
2111
- skb_shinfo ( skb ) -> gso_segs = 0 ;
2116
+ shinfo -> gso_type |= SKB_GSO_DODGY ;
2117
+ shinfo -> gso_segs = 0 ;
2112
2118
}
2113
2119
2114
2120
skb -> protocol = htons (ETH_P_IPV6 );
@@ -2123,6 +2129,10 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
2123
2129
u32 off = skb_mac_header_len (skb );
2124
2130
int ret ;
2125
2131
2132
+ /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2133
+ if (skb_is_gso (skb ) && unlikely (skb_is_gso_sctp (skb )))
2134
+ return - ENOTSUPP ;
2135
+
2126
2136
ret = skb_unclone (skb , GFP_ATOMIC );
2127
2137
if (unlikely (ret < 0 ))
2128
2138
return ret ;
@@ -2132,19 +2142,21 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
2132
2142
return ret ;
2133
2143
2134
2144
if (skb_is_gso (skb )) {
2145
+ struct skb_shared_info * shinfo = skb_shinfo (skb );
2146
+
2135
2147
/* SKB_GSO_TCPV6 needs to be changed into
2136
2148
* SKB_GSO_TCPV4.
2137
2149
*/
2138
- if (skb_shinfo ( skb ) -> gso_type & SKB_GSO_TCPV6 ) {
2139
- skb_shinfo ( skb ) -> gso_type &= ~SKB_GSO_TCPV6 ;
2140
- skb_shinfo ( skb ) -> gso_type |= SKB_GSO_TCPV4 ;
2150
+ if (shinfo -> gso_type & SKB_GSO_TCPV6 ) {
2151
+ shinfo -> gso_type &= ~SKB_GSO_TCPV6 ;
2152
+ shinfo -> gso_type |= SKB_GSO_TCPV4 ;
2141
2153
}
2142
2154
2143
2155
/* Due to IPv4 header, MSS can be upgraded. */
2144
- skb_shinfo ( skb ) -> gso_size += len_diff ;
2156
+ skb_increase_gso_size ( shinfo , len_diff ) ;
2145
2157
/* Header must be checked, and gso_segs recomputed. */
2146
- skb_shinfo ( skb ) -> gso_type |= SKB_GSO_DODGY ;
2147
- skb_shinfo ( skb ) -> gso_segs = 0 ;
2158
+ shinfo -> gso_type |= SKB_GSO_DODGY ;
2159
+ shinfo -> gso_segs = 0 ;
2148
2160
}
2149
2161
2150
2162
skb -> protocol = htons (ETH_P_IP );
@@ -2243,6 +2255,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff)
2243
2255
u32 off = skb_mac_header_len (skb ) + bpf_skb_net_base_len (skb );
2244
2256
int ret ;
2245
2257
2258
+ /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2259
+ if (skb_is_gso (skb ) && unlikely (skb_is_gso_sctp (skb )))
2260
+ return - ENOTSUPP ;
2261
+
2246
2262
ret = skb_cow (skb , len_diff );
2247
2263
if (unlikely (ret < 0 ))
2248
2264
return ret ;
@@ -2252,11 +2268,13 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff)
2252
2268
return ret ;
2253
2269
2254
2270
if (skb_is_gso (skb )) {
2271
+ struct skb_shared_info * shinfo = skb_shinfo (skb );
2272
+
2255
2273
/* Due to header grow, MSS needs to be downgraded. */
2256
- skb_shinfo ( skb ) -> gso_size -= len_diff ;
2274
+ skb_decrease_gso_size ( shinfo , len_diff ) ;
2257
2275
/* Header must be checked, and gso_segs recomputed. */
2258
- skb_shinfo ( skb ) -> gso_type |= SKB_GSO_DODGY ;
2259
- skb_shinfo ( skb ) -> gso_segs = 0 ;
2276
+ shinfo -> gso_type |= SKB_GSO_DODGY ;
2277
+ shinfo -> gso_segs = 0 ;
2260
2278
}
2261
2279
2262
2280
return 0 ;
@@ -2267,6 +2285,10 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff)
2267
2285
u32 off = skb_mac_header_len (skb ) + bpf_skb_net_base_len (skb );
2268
2286
int ret ;
2269
2287
2288
+ /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2289
+ if (skb_is_gso (skb ) && unlikely (skb_is_gso_sctp (skb )))
2290
+ return - ENOTSUPP ;
2291
+
2270
2292
ret = skb_unclone (skb , GFP_ATOMIC );
2271
2293
if (unlikely (ret < 0 ))
2272
2294
return ret ;
@@ -2276,11 +2298,13 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff)
2276
2298
return ret ;
2277
2299
2278
2300
if (skb_is_gso (skb )) {
2301
+ struct skb_shared_info * shinfo = skb_shinfo (skb );
2302
+
2279
2303
/* Due to header shrink, MSS can be upgraded. */
2280
- skb_shinfo ( skb ) -> gso_size += len_diff ;
2304
+ skb_increase_gso_size ( shinfo , len_diff ) ;
2281
2305
/* Header must be checked, and gso_segs recomputed. */
2282
- skb_shinfo ( skb ) -> gso_type |= SKB_GSO_DODGY ;
2283
- skb_shinfo ( skb ) -> gso_segs = 0 ;
2306
+ shinfo -> gso_type |= SKB_GSO_DODGY ;
2307
+ shinfo -> gso_segs = 0 ;
2284
2308
}
2285
2309
2286
2310
return 0 ;
0 commit comments