aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_connection_sock.h2
-rw-r--r--net/dccp/ipv4.c11
-rw-r--r--net/ipv4/inet_connection_sock.c46
-rw-r--r--net/ipv4/tcp_ipv4.c11
4 files changed, 52 insertions, 18 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 291e7cee14e7..2cf44b4ed2e6 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -337,4 +337,6 @@ extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
337 char __user *optval, int __user *optlen); 337 char __user *optval, int __user *optlen);
338extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, 338extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
339 char __user *optval, unsigned int optlen); 339 char __user *optval, unsigned int optlen);
340
341extern struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu);
340#endif /* _INET_CONNECTION_SOCK_H */ 342#endif /* _INET_CONNECTION_SOCK_H */
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 129ed8f74138..683902fcc8ed 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -161,17 +161,10 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
161 if (sk->sk_state == DCCP_LISTEN) 161 if (sk->sk_state == DCCP_LISTEN)
162 return; 162 return;
163 163
164 /* We don't check in the destentry if pmtu discovery is forbidden 164 dst = inet_csk_update_pmtu(sk, mtu);
165 * on this route. We just assume that no packet_to_big packets 165 if (!dst)
166 * are send back when pmtu discovery is not active.
167 * There is a small race when the user changes this flag in the
168 * route, but I think that's acceptable.
169 */
170 if ((dst = __sk_dst_check(sk, 0)) == NULL)
171 return; 166 return;
172 167
173 dst->ops->update_pmtu(dst, mtu);
174
175 /* Something is about to be wrong... Remember soft error 168 /* Something is about to be wrong... Remember soft error
176 * for the case, if this connection will not able to recover. 169 * for the case, if this connection will not able to recover.
177 */ 170 */
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 76825be3b643..200d21809379 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -803,3 +803,49 @@ int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
803} 803}
804EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt); 804EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt);
805#endif 805#endif
806
807static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl)
808{
809 struct inet_sock *inet = inet_sk(sk);
810 struct ip_options_rcu *inet_opt;
811 __be32 daddr = inet->inet_daddr;
812 struct flowi4 *fl4;
813 struct rtable *rt;
814
815 rcu_read_lock();
816 inet_opt = rcu_dereference(inet->inet_opt);
817 if (inet_opt && inet_opt->opt.srr)
818 daddr = inet_opt->opt.faddr;
819 fl4 = &fl->u.ip4;
820 rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr,
821 inet->inet_saddr, inet->inet_dport,
822 inet->inet_sport, sk->sk_protocol,
823 RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
824 if (IS_ERR(rt))
825 rt = NULL;
826 if (rt)
827 sk_setup_caps(sk, &rt->dst);
828 rcu_read_unlock();
829
830 return &rt->dst;
831}
832
833struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu)
834{
835 struct dst_entry *dst = __sk_dst_check(sk, 0);
836 struct inet_sock *inet = inet_sk(sk);
837
838 if (!dst) {
839 dst = inet_csk_rebuild_route(sk, &inet->cork.fl);
840 if (!dst)
841 goto out;
842 }
843 dst->ops->update_pmtu(dst, mtu);
844
845 dst = __sk_dst_check(sk, 0);
846 if (!dst)
847 dst = inet_csk_rebuild_route(sk, &inet->cork.fl);
848out:
849 return dst;
850}
851EXPORT_SYMBOL_GPL(inet_csk_update_pmtu);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 7a0062cb4ed0..b8e7e0595407 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -289,17 +289,10 @@ static void do_pmtu_discovery(struct sock *sk, const struct iphdr *iph, u32 mtu)
289 if (sk->sk_state == TCP_LISTEN) 289 if (sk->sk_state == TCP_LISTEN)
290 return; 290 return;
291 291
292 /* We don't check in the destentry if pmtu discovery is forbidden 292 dst = inet_csk_update_pmtu(sk, mtu);
293 * on this route. We just assume that no packet_to_big packets 293 if (!dst)
294 * are send back when pmtu discovery is not active.
295 * There is a small race when the user changes this flag in the
296 * route, but I think that's acceptable.
297 */
298 if ((dst = __sk_dst_check(sk, 0)) == NULL)
299 return; 294 return;
300 295
301 dst->ops->update_pmtu(dst, mtu);
302
303 /* Something is about to be wrong... Remember soft error 296 /* Something is about to be wrong... Remember soft error
304 * for the case, if this connection will not able to recover. 297 * for the case, if this connection will not able to recover.
305 */ 298 */