]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/route.c
ipv4: introduce ip_dst_mtu_maybe_forward and protect forwarding path against pmtu...
[~andy/linux] / net / ipv4 / route.c
index 6011615e810d397ce8ffa5daeca58ce6921e85f0..25071b48921cebc4788a1f4b0b5fa118832f5910 100644 (file)
 #define RT_FL_TOS(oldflp4) \
        ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))
 
-/* IPv4 datagram length is stored into 16bit field (tot_len) */
-#define IP_MAX_MTU     0xFFFF
-
 #define RT_GC_TIMEOUT (300*HZ)
 
 static int ip_rt_max_size;
@@ -295,7 +292,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
        seq_printf(seq,"%08x  %08x %08x %08x %08x %08x %08x %08x "
                   " %08x %08x %08x %08x %08x %08x %08x %08x %08x \n",
                   dst_entries_get_slow(&ipv4_dst_ops),
-                  st->in_hit,
+                  0, /* st->in_hit */
                   st->in_slow_tot,
                   st->in_slow_mc,
                   st->in_no_route,
@@ -303,16 +300,16 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
                   st->in_martian_dst,
                   st->in_martian_src,
 
-                  st->out_hit,
+                  0, /* st->out_hit */
                   st->out_slow_tot,
                   st->out_slow_mc,
 
-                  st->gc_total,
-                  st->gc_ignored,
-                  st->gc_goal_miss,
-                  st->gc_dst_overflow,
-                  st->in_hlist_search,
-                  st->out_hlist_search
+                  0, /* st->gc_total */
+                  0, /* st->gc_ignored */
+                  0, /* st->gc_goal_miss */
+                  0, /* st->gc_dst_overflow */
+                  0, /* st->in_hlist_search */
+                  0  /* st->out_hlist_search */
                );
        return 0;
 }
@@ -1036,6 +1033,10 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
        bool new = false;
 
        bh_lock_sock(sk);
+
+       if (!ip_sk_accept_pmtu(sk))
+               goto out;
+
        rt = (struct rtable *) __sk_dst_get(sk);
 
        if (sock_owned_by_user(sk) || !rt) {
@@ -1772,8 +1773,12 @@ local_input:
                rth->dst.error= -err;
                rth->rt_flags   &= ~RTCF_LOCAL;
        }
-       if (do_cache)
-               rt_cache_route(&FIB_RES_NH(res), rth);
+       if (do_cache) {
+               if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
+                       rth->dst.flags |= DST_NOCACHE;
+                       rt_add_uncached_list(rth);
+               }
+       }
        skb_dst_set(skb, &rth->dst);
        err = 0;
        goto out;