aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r--net/ipv4/icmp.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 5c0e8bc6e5ba..0134663fdbce 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -668,6 +668,16 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
668 rcu_read_unlock(); 668 rcu_read_unlock();
669} 669}
670 670
671static bool icmp_tag_validation(int proto)
672{
673 bool ok;
674
675 rcu_read_lock();
676 ok = rcu_dereference(inet_protos[proto])->icmp_strict_tag_validation;
677 rcu_read_unlock();
678 return ok;
679}
680
671/* 681/*
672 * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, ICMP_QUENCH, and 682 * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, ICMP_QUENCH, and
673 * ICMP_PARAMETERPROB. 683 * ICMP_PARAMETERPROB.
@@ -705,10 +715,22 @@ static void icmp_unreach(struct sk_buff *skb)
705 case ICMP_PORT_UNREACH: 715 case ICMP_PORT_UNREACH:
706 break; 716 break;
707 case ICMP_FRAG_NEEDED: 717 case ICMP_FRAG_NEEDED:
708 if (ipv4_config.no_pmtu_disc) { 718 /* for documentation of the ip_no_pmtu_disc
719 * values please see
720 * Documentation/networking/ip-sysctl.txt
721 */
722 switch (net->ipv4.sysctl_ip_no_pmtu_disc) {
723 default:
709 LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"), 724 LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"),
710 &iph->daddr); 725 &iph->daddr);
711 } else { 726 break;
727 case 2:
728 goto out;
729 case 3:
730 if (!icmp_tag_validation(iph->protocol))
731 goto out;
732 /* fall through */
733 case 0:
712 info = ntohs(icmph->un.frag.mtu); 734 info = ntohs(icmph->un.frag.mtu);
713 if (!info) 735 if (!info)
714 goto out; 736 goto out;