X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv4%2Fip_forward.c;h=8c95cf09f87ac213e81b0a2421d568a4a7a6bd92;hb=40b42f1ebf653cd72c32eb1a1a0b9fea2dfbfd7d;hp=a22d11d2911cd4f7772b2d6428a5d525c5cc2f59;hpb=c4e00fac42f268ed0a547cdd1d12bb8399864040;p=linux-2.6 diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index a22d11d291..8c95cf09f8 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -4,15 +4,15 @@ * interface as the means of communication with the user level. * * The IP forwarding functionality. - * + * * Version: $Id: ip_forward.c,v 1.48 2000/12/13 18:31:48 davem Exp $ * * Authors: see ip.c * * Fixes: - * Many : Split from ip.c , see ip_input.c for + * Many : Split from ip.c , see ip_input.c for * history. - * Dave Gregorich : NULL ip_rt_put fix for multicast + * Dave Gregorich : NULL ip_rt_put fix for multicast * routing. * Jos Vos : Add call_out_firewall before sending, * use output device for accounting. @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -68,15 +67,15 @@ int ip_forward(struct sk_buff *skb) if (skb->pkt_type != PACKET_HOST) goto drop; - skb->ip_summed = CHECKSUM_NONE; - + skb_forward_csum(skb); + /* * According to the RFC, we must first decrease the TTL field. If * that reaches zero, we must reply an ICMP control message telling * that the packet's lifetime expired. */ - if (skb->nh.iph->ttl <= 1) - goto too_many_hops; + if (ip_hdr(skb)->ttl <= 1) + goto too_many_hops; if (!xfrm4_route_forward(skb)) goto drop; @@ -86,10 +85,18 @@ int ip_forward(struct sk_buff *skb) if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto sr_failed; + if (unlikely(skb->len > dst_mtu(&rt->u.dst) && + (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { + IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(dst_mtu(&rt->u.dst))); + goto drop; + } + /* We are about to mangle packet. Copy it! */ if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len)) goto drop; - iph = skb->nh.iph; + iph = ip_hdr(skb); /* Decrease ttl after skb cow done */ ip_decrease_ttl(iph); @@ -107,16 +114,16 @@ int ip_forward(struct sk_buff *skb) ip_forward_finish); sr_failed: - /* + /* * Strict routing permits no gatewaying */ - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0); - goto drop; + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0); + goto drop; too_many_hops: - /* Tell the sender its packet died... */ - IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); - icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); + /* Tell the sender its packet died... */ + IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); + icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); drop: kfree_skb(skb); return NET_RX_DROP;