Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv4: fix error handling in icmp_protocol.

Now we handle icmp errors in each transport protocol's err_handler,
for icmp protocols, that is ping_err. Since this handler only care
of those icmp errors triggered by echo request, errors triggered
by echo reply(which sent by kernel) are sliently ignored.

So wrap ping_err() with icmp_err() to deal with those icmp errors.

Signed-off-by: Li Wei <lw@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Li Wei and committed by
David S. Miller
5b052042 08dcdbf6

+25 -1
+1
include/net/icmp.h
··· 41 41 42 42 extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); 43 43 extern int icmp_rcv(struct sk_buff *skb); 44 + extern void icmp_err(struct sk_buff *, u32 info); 44 45 extern int icmp_init(void); 45 46 extern void icmp_out_count(struct net *net, unsigned char type); 46 47
+1 -1
net/ipv4/af_inet.c
··· 1577 1577 1578 1578 static const struct net_protocol icmp_protocol = { 1579 1579 .handler = icmp_rcv, 1580 - .err_handler = ping_err, 1580 + .err_handler = icmp_err, 1581 1581 .no_policy = 1, 1582 1582 .netns_ok = 1, 1583 1583 };
+23
net/ipv4/icmp.c
··· 934 934 goto drop; 935 935 } 936 936 937 + void icmp_err(struct sk_buff *skb, u32 info) 938 + { 939 + struct iphdr *iph = (struct iphdr *)skb->data; 940 + struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2)); 941 + int type = icmp_hdr(skb)->type; 942 + int code = icmp_hdr(skb)->code; 943 + struct net *net = dev_net(skb->dev); 944 + 945 + /* 946 + * Use ping_err to handle all icmp errors except those 947 + * triggered by ICMP_ECHOREPLY which sent from kernel. 948 + */ 949 + if (icmph->type != ICMP_ECHOREPLY) { 950 + ping_err(skb, info); 951 + return; 952 + } 953 + 954 + if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) 955 + ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0); 956 + else if (type == ICMP_REDIRECT) 957 + ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0); 958 + } 959 + 937 960 /* 938 961 * This table is the definition of how we handle ICMP. 939 962 */