aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/icmp.h1
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/icmp.c23
3 files changed, 25 insertions, 1 deletions
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 9ac2524d1402..081439fd070e 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -41,6 +41,7 @@ struct net;
41 41
42extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); 42extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
43extern int icmp_rcv(struct sk_buff *skb); 43extern int icmp_rcv(struct sk_buff *skb);
44extern void icmp_err(struct sk_buff *, u32 info);
44extern int icmp_init(void); 45extern int icmp_init(void);
45extern void icmp_out_count(struct net *net, unsigned char type); 46extern void icmp_out_count(struct net *net, unsigned char type);
46 47
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 9cbcb94a4c6d..15847e19b7dd 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1577,7 +1577,7 @@ static const struct net_offload udp_offload = {
1577 1577
1578static const struct net_protocol icmp_protocol = { 1578static const struct net_protocol icmp_protocol = {
1579 .handler = icmp_rcv, 1579 .handler = icmp_rcv,
1580 .err_handler = ping_err, 1580 .err_handler = icmp_err,
1581 .no_policy = 1, 1581 .no_policy = 1,
1582 .netns_ok = 1, 1582 .netns_ok = 1,
1583}; 1583};
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 17ff9fd7cdda..3ac5dff79627 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -934,6 +934,29 @@ error:
934 goto drop; 934 goto drop;
935} 935}
936 936
937void 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 * This table is the definition of how we handle ICMP. 961 * This table is the definition of how we handle ICMP.
939 */ 962 */