@@ -1093,11 +1093,12 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
1093
1093
return src ? kmemdup (src , (src -> hdrlen + 1 ) * 8 , gfp ) : NULL ;
1094
1094
}
1095
1095
1096
- static void ip6_append_data_mtu (int * mtu ,
1096
+ static void ip6_append_data_mtu (unsigned int * mtu ,
1097
1097
int * maxfraglen ,
1098
1098
unsigned int fragheaderlen ,
1099
1099
struct sk_buff * skb ,
1100
- struct rt6_info * rt )
1100
+ struct rt6_info * rt ,
1101
+ bool pmtuprobe )
1101
1102
{
1102
1103
if (!(rt -> dst .flags & DST_XFRM_TUNNEL )) {
1103
1104
if (skb == NULL ) {
@@ -1109,7 +1110,9 @@ static void ip6_append_data_mtu(int *mtu,
1109
1110
* this fragment is not first, the headers
1110
1111
* space is regarded as data space.
1111
1112
*/
1112
- * mtu = dst_mtu (rt -> dst .path );
1113
+ * mtu = min (* mtu , pmtuprobe ?
1114
+ rt -> dst .dev -> mtu :
1115
+ dst_mtu (rt -> dst .path ));
1113
1116
}
1114
1117
* maxfraglen = ((* mtu - fragheaderlen ) & ~7 )
1115
1118
+ fragheaderlen - sizeof (struct frag_hdr );
@@ -1126,11 +1129,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1126
1129
struct ipv6_pinfo * np = inet6_sk (sk );
1127
1130
struct inet_cork * cork ;
1128
1131
struct sk_buff * skb , * skb_prev = NULL ;
1129
- unsigned int maxfraglen , fragheaderlen ;
1132
+ unsigned int maxfraglen , fragheaderlen , mtu ;
1130
1133
int exthdrlen ;
1131
1134
int dst_exthdrlen ;
1132
1135
int hh_len ;
1133
- int mtu ;
1134
1136
int copy ;
1135
1137
int err ;
1136
1138
int offset = 0 ;
@@ -1287,7 +1289,9 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1287
1289
/* update mtu and maxfraglen if necessary */
1288
1290
if (skb == NULL || skb_prev == NULL )
1289
1291
ip6_append_data_mtu (& mtu , & maxfraglen ,
1290
- fragheaderlen , skb , rt );
1292
+ fragheaderlen , skb , rt ,
1293
+ np -> pmtudisc ==
1294
+ IPV6_PMTUDISC_PROBE );
1291
1295
1292
1296
skb_prev = skb ;
1293
1297
0 commit comments