aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2018-01-25 13:03:03 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-25 16:27:34 -0500
commitf15ca723c1ebe6c1a06bc95fda6b62cd87b44559 (patch)
treed81f5825fe96dbfc589b19561961814fed78b4fc /net
parent4ee806d51176ba7b8ff1efd81f271d7252e03a1d (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.c3
-rw-r--r--net/ipv4/ip_vti.c2
-rw-r--r--net/ipv6/ip6_tunnel.c6
-rw-r--r--net/ipv6/ip6_vti.c2
-rw-r--r--net/ipv6/sit.c4
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);