Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.24.4 /net/ipv6/ip6_output.c

Filename:/net/ipv6/ip6_output.c
Lines Added:8
Lines Deleted:2
Also changed in: (Previous) 2.6.24.4-rc3  2.6.24.4-rc2  2.6.24.4-rc1  2.6.24.3  2.6.24.3-rc1  2.6.24-git22 
(Following) 2.6.24.5  2.6.24.6  2.6.24.7  2.6.25-rc7  2.6.25-rc8  2.6.25-rc9 

Location
[  2.6.24.4
  [  net
    [  ipv6
       o  ip6_output.c

Patch

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3bef30e..5b4095b 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -593,7 +593,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
     * or if the skb it not generated by a local socket.  (This last
     * check should be redundant, but it's free.)
     */
-   if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
+   if (!skb->local_df) {
       skb->dev = skb->dst->dev;
       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
       IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
@@ -609,6 +609,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
    if (skb_shinfo(skb)->frag_list) {
       int first_len = skb_pagelen(skb);
+      int truesizes = 0;
 
       if (first_len - hlen > mtu ||
           ((first_len - hlen) & 7) ||
@@ -631,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
             sock_hold(skb->sk);
             frag->sk = skb->sk;
             frag->destructor = sock_wfree;
-            skb->truesize -= frag->truesize;
+            truesizes += frag->truesize;
          }
       }
 
@@ -662,6 +663,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
       first_len = skb_pagelen(skb);
       skb->data_len = first_len - skb_headlen(skb);
+      skb->truesize -= truesizes;
       skb->len = first_len;
       ipv6_hdr(skb)->payload_len = htons(first_len -
                      sizeof(struct ipv6hdr));
@@ -1387,6 +1389,10 @@ int ip6_push_pending_frames(struct sock *sk)
       tmp_skb->sk = NULL;
    }
 
+   /* Allow local fragmentation. */
+   if (np->pmtudisc < IPV6_PMTUDISC_DO)
+      skb->local_df = 1;
+
    ipv6_addr_copy(final_dst, &fl->fl6_dst);
    __skb_pull(skb, skb_network_header_len(skb));
    if (opt && opt->opt_flen)


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.