diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2018-01-25 13:03:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-25 16:27:34 -0500 |
commit | f15ca723c1ebe6c1a06bc95fda6b62cd87b44559 (patch) | |
tree | d81f5825fe96dbfc589b19561961814fed78b4fc /net | |
parent | 4ee806d51176ba7b8ff1efd81f271d7252e03a1d (diff) |
net: don't call update_pmtu unconditionally
Some dst_ops (e.g. md_dst_ops)) doesn't set this handler. It may result to:
"BUG: unable to handle kernel NULL pointer dereference at (null)"
Let's add a helper to check if update_pmtu is available before calling it.
Fixes: 52a589d51f10 ("geneve: update skb dst pmtu on tx path")
Fixes: a93bf0ff4490 ("vxlan: update skb dst pmtu on tx path")
CC: Roman Kapl <code@rkapl.cz>
CC: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ip_tunnel.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6_vti.c | 2 | ||||
-rw-r--r-- | net/ipv6/sit.c | 4 |
5 files changed, 7 insertions, 10 deletions
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 5ddb1cb52bd4..6d21068f9b55 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -520,8 +520,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, | |||
520 | else | 520 | else |
521 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | 521 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
522 | 522 | ||
523 | if (skb_dst(skb)) | 523 | skb_dst_update_pmtu(skb, mtu); |
524 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
525 | 524 | ||
526 | if (skb->protocol == htons(ETH_P_IP)) { | 525 | if (skb->protocol == htons(ETH_P_IP)) { |
527 | if (!skb_is_gso(skb) && | 526 | if (!skb_is_gso(skb) && |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 949f432a5f04..51b1669334fe 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -200,7 +200,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, | |||
200 | 200 | ||
201 | mtu = dst_mtu(dst); | 201 | mtu = dst_mtu(dst); |
202 | if (skb->len > mtu) { | 202 | if (skb->len > mtu) { |
203 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 203 | skb_dst_update_pmtu(skb, mtu); |
204 | if (skb->protocol == htons(ETH_P_IP)) { | 204 | if (skb->protocol == htons(ETH_P_IP)) { |
205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
206 | htonl(mtu)); | 206 | htonl(mtu)); |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9a7cf355bc8c..1ee5584c3555 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -642,8 +642,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
642 | if (rel_info > dst_mtu(skb_dst(skb2))) | 642 | if (rel_info > dst_mtu(skb_dst(skb2))) |
643 | goto out; | 643 | goto out; |
644 | 644 | ||
645 | skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2, | 645 | skb_dst_update_pmtu(skb2, rel_info); |
646 | rel_info); | ||
647 | } | 646 | } |
648 | 647 | ||
649 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); | 648 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); |
@@ -1131,8 +1130,7 @@ route_lookup: | |||
1131 | mtu = 576; | 1130 | mtu = 576; |
1132 | } | 1131 | } |
1133 | 1132 | ||
1134 | if (skb_dst(skb) && !t->parms.collect_md) | 1133 | skb_dst_update_pmtu(skb, mtu); |
1135 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
1136 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { | 1134 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { |
1137 | *pmtu = mtu; | 1135 | *pmtu = mtu; |
1138 | err = -EMSGSIZE; | 1136 | err = -EMSGSIZE; |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index dbb74f3c57a7..8c184f84f353 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -483,7 +483,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
483 | 483 | ||
484 | mtu = dst_mtu(dst); | 484 | mtu = dst_mtu(dst); |
485 | if (!skb->ignore_df && skb->len > mtu) { | 485 | if (!skb->ignore_df && skb->len > mtu) { |
486 | skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); | 486 | skb_dst_update_pmtu(skb, mtu); |
487 | 487 | ||
488 | if (skb->protocol == htons(ETH_P_IPV6)) { | 488 | if (skb->protocol == htons(ETH_P_IPV6)) { |
489 | if (mtu < IPV6_MIN_MTU) | 489 | if (mtu < IPV6_MIN_MTU) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d7dc23c1b2ca..3873d3877135 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -934,8 +934,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
934 | df = 0; | 934 | df = 0; |
935 | } | 935 | } |
936 | 936 | ||
937 | if (tunnel->parms.iph.daddr && skb_dst(skb)) | 937 | if (tunnel->parms.iph.daddr) |
938 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 938 | skb_dst_update_pmtu(skb, mtu); |
939 | 939 | ||
940 | if (skb->len > mtu && !skb_is_gso(skb)) { | 940 | if (skb->len > mtu && !skb_is_gso(skb)) { |
941 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 941 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |