aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-15 01:21:46 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-15 01:22:07 -0400
commit36393395536064e483b73d173f6afc103eadfbc4 (patch)
treeb45113cce1bdfc4be92a856700690a253f1bb088 /net/ipv4/route.c
parentb3908e22ad8bb6074934496ef171fd83605d7d3e (diff)
ipv4: Handle PMTU in all ICMP error handlers.
With ip_rt_frag_needed() removed, we have to explicitly update PMTU information in every ICMP error handler. Create two helper functions to facilitate this. 1) ipv4_sk_update_pmtu() This updates the PMTU when we have a socket context to work with. 2) ipv4_update_pmtu() Raw version, used when no socket context is available. For this interface, we essentially just pass in explicit arguments for the flow identity information we would have extracted from the socket. And you'll notice that ipv4_sk_update_pmtu() is simply implemented in terms of ipv4_update_pmtu() Note that __ip_route_output_key() is used, rather than something like ip_route_output_flow() or ip_route_output_key(). This is because we absolutely do not want to end up with a route that does IPSEC encapsulation and the like. Instead, we only want the route that would get us to the node described by the outermost IP header. Reported-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 655506af47ca..41df5297a412 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1711,6 +1711,34 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
1711 } 1711 }
1712} 1712}
1713 1713
1714void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
1715 int oif, u32 mark, u8 protocol, int flow_flags)
1716{
1717 const struct iphdr *iph = (const struct iphdr *)skb->data;
1718 struct flowi4 fl4;
1719 struct rtable *rt;
1720
1721 flowi4_init_output(&fl4, oif, mark, RT_TOS(iph->tos), RT_SCOPE_UNIVERSE,
1722 protocol, flow_flags | FLOWI_FLAG_PRECOW_METRICS,
1723 iph->daddr, iph->saddr, 0, 0);
1724 rt = __ip_route_output_key(net, &fl4);
1725 if (!IS_ERR(rt)) {
1726 ip_rt_update_pmtu(&rt->dst, mtu);
1727 ip_rt_put(rt);
1728 }
1729}
1730EXPORT_SYMBOL_GPL(ipv4_update_pmtu);
1731
1732void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
1733{
1734 const struct inet_sock *inet = inet_sk(sk);
1735
1736 return ipv4_update_pmtu(skb, sock_net(sk), mtu,
1737 sk->sk_bound_dev_if, sk->sk_mark,
1738 inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
1739 inet_sk_flowi_flags(sk));
1740}
1741EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu);
1714 1742
1715static void ipv4_validate_peer(struct rtable *rt) 1743static void ipv4_validate_peer(struct rtable *rt)
1716{ 1744{