aboutsummaryrefslogtreecommitdiff
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorGary S. Robertson <gary.robertson@linaro.org>2014-03-12 16:35:51 -0500
committerGary S. Robertson <gary.robertson@linaro.org>2014-03-12 16:35:51 -0500
commit9ce234e1ee801968b204c3b9caa75ce0a76ed1c2 (patch)
tree850b06a09068c82c95dcb8419f344749392fe527 /net/ipv6/ip6_output.c
parentde4c0af15b38d383e79555be2d72e7958f1c0756 (diff)
parent6969595f011b46b49c3f1b9e0bd7da27768c1fd9 (diff)
Merge tag 'v3.10.33' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into linux-lnglinux-lng-v3.10.33-finallinux-lng-3.10.33-2014.03
This is the 3.10.33 stable release
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index b98b8e06739e..98a262b759ae 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -345,6 +345,20 @@ static inline int ip6_forward_finish(struct sk_buff *skb)
return dst_output(skb);
}
+static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
+{
+ if (skb->len <= mtu || skb->local_df)
+ return false;
+
+ if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)
+ return true;
+
+ if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
+ return false;
+
+ return true;
+}
+
int ip6_forward(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
@@ -467,8 +481,7 @@ int ip6_forward(struct sk_buff *skb)
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
- if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
- (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {
+ if (ip6_pkt_too_big(skb, mtu)) {
/* Again, force OUTPUT device used as source address */
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);