diff -ur linux-sane/include/linux/sysctl.h linux/include/linux/sysctl.h --- linux-sane/include/linux/sysctl.h Fri Jul 20 21:52:18 2001 +++ linux/include/linux/sysctl.h Fri Aug 3 13:22:56 2001 @@ -251,11 +251,18 @@ NET_IPV4_LOCAL_PORT_RANGE=56, NET_IPV4_ICMP_ECHO_IGNORE_ALL=57, NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS=58, - NET_IPV4_ICMP_SOURCEQUENCH_RATE=59, - NET_IPV4_ICMP_DESTUNREACH_RATE=60, - NET_IPV4_ICMP_TIMEEXCEED_RATE=61, - NET_IPV4_ICMP_PARAMPROB_RATE=62, - NET_IPV4_ICMP_ECHOREPLY_RATE=63, + +/* obsolet, replaced by global icmp limiting. + + NET_IPV4_ICMP_SOURCEQUENCH_RATE, + NET_IPV4_ICMP_DESTUNREACH_RATE, + NET_IPV4_ICMP_TIMEEXCEED_RATE, + NET_IPV4_ICMP_PARAMPROB_RATE, + NET_IPV4_ICMP_ECHOREPLY_RATE, + + use NET_IPV4_ICMP_RATELIMIT, NET_IPV4_ICMP_RATEMASK instead + +*/ NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64, NET_IPV4_IGMP_MAX_MEMBERSHIPS=65, NET_TCP_TW_RECYCLE=66, @@ -281,6 +288,8 @@ NET_TCP_APP_WIN=86, NET_TCP_ADV_WIN_SCALE=87, NET_IPV4_NONLOCAL_BIND=88, + NET_IPV4_ICMP_RATELIMIT=89, + NET_IPV4_ICMP_RATEMASK=90 }; enum { diff -ur linux-sane/net/ipv4/icmp.c linux/net/ipv4/icmp.c --- linux-sane/net/ipv4/icmp.c Thu Jun 21 06:00:55 2001 +++ linux/net/ipv4/icmp.c Fri Aug 3 13:29:46 2001 @@ -16,6 +16,9 @@ * Other than that this module is a complete rewrite. * * Fixes: + * Clemens Fruhwirth : introduce global icmp rate limiting + * with icmp type masking ability instead + * of broken per type icmp timeouts. * Mike Shaver : RFC1122 checks. * Alan Cox : Multicast ping reply as self. * Alan Cox : Fix atomicity lockup in ip_build_xmit @@ -145,6 +148,23 @@ /* Control parameter - ignore bogus broadcast responses? */ int sysctl_icmp_ignore_bogus_error_responses; +/* + * Configurable global rate limit. + * + * ratelimit defines token/tick for dst->rate_token bucket + * ratemask defines which icmp types are ratelimited by setting + * it's bit position. + * + * FIXME: verify if the defaults are reasonable + * + * default: + * dest unreachable (0x03), source quench (0x04), + * time exceeded (0x11), parameter problem (0x12) + */ + +int sysctl_icmp_ratelimit = 1*HZ; +int sysctl_icmp_ratemask = 0x1818; + /* * ICMP control array. This specifies what to do with each ICMP. */ @@ -155,7 +175,6 @@ unsigned long *input; /* Address to increment on input */ void (*handler)(struct sk_buff *skb); short error; /* This ICMP is classed as an error message */ - int *timeout; /* Rate limit */ }; static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; @@ -257,22 +276,21 @@ { struct dst_entry *dst = &rt->u.dst; - if (type > NR_ICMP_TYPES || !icmp_pointers[type].timeout) + if (type > NR_ICMP_TYPES) return 1; /* Don't limit PMTU discovery. */ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) return 1; - /* Redirect has its own rate limit mechanism */ - if (type == ICMP_REDIRECT) - return 1; - /* No rate limit on loopback */ if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) return 1; - return xrlim_allow(dst, *(icmp_pointers[type].timeout)); + if((1 << type) & sysctl_icmp_ratemask) + return xrlim_allow(dst,sysctl_icmp_ratelimit); + else + return 1; } /* @@ -929,18 +947,7 @@ } -/* - * Configurable rate limits. - * Someone should check if these default values are correct. - * Note that these values interact with the routing cache GC timeout. - * If you chose them too high they won't take effect, because the - * dst_entry gets expired too early. The same should happen when - * the cache grows too big. - */ -int sysctl_icmp_destunreach_time = 1*HZ; -int sysctl_icmp_timeexceed_time = 1*HZ; -int sysctl_icmp_paramprob_time = 1*HZ; -int sysctl_icmp_echoreply_time; /* don't limit it per default. */ + /* * This table is the definition of how we handle ICMP. @@ -948,37 +955,37 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1] = { /* ECHO REPLY (0) */ - { &icmp_statistics[0].IcmpOutEchoReps, &icmp_statistics[0].IcmpInEchoReps, icmp_discard, 0, &sysctl_icmp_echoreply_time}, - { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, }, - { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, }, + { &icmp_statistics[0].IcmpOutEchoReps, &icmp_statistics[0].IcmpInEchoReps, icmp_discard, 0 }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 }, /* DEST UNREACH (3) */ - { &icmp_statistics[0].IcmpOutDestUnreachs, &icmp_statistics[0].IcmpInDestUnreachs, icmp_unreach, 1, &sysctl_icmp_destunreach_time }, + { &icmp_statistics[0].IcmpOutDestUnreachs, &icmp_statistics[0].IcmpInDestUnreachs, icmp_unreach, 1 }, /* SOURCE QUENCH (4) */ - { &icmp_statistics[0].IcmpOutSrcQuenchs, &icmp_statistics[0].IcmpInSrcQuenchs, icmp_unreach, 1, }, + { &icmp_statistics[0].IcmpOutSrcQuenchs, &icmp_statistics[0].IcmpInSrcQuenchs, icmp_unreach, 1 }, /* REDIRECT (5) */ - { &icmp_statistics[0].IcmpOutRedirects, &icmp_statistics[0].IcmpInRedirects, icmp_redirect, 1, }, - { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, }, - { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, }, + { &icmp_statistics[0].IcmpOutRedirects, &icmp_statistics[0].IcmpInRedirects, icmp_redirect, 1 }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 }, /* ECHO (8) */ - { &icmp_statistics[0].IcmpOutEchos, &icmp_statistics[0].IcmpInEchos, icmp_echo, 0, }, - { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, }, - { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, }, + { &icmp_statistics[0].IcmpOutEchos, &icmp_statistics[0].IcmpInEchos, icmp_echo, 0 }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 }, /* TIME EXCEEDED (11) */ - { &icmp_statistics[0].IcmpOutTimeExcds, &icmp_statistics[0].IcmpInTimeExcds, icmp_unreach, 1, &sysctl_icmp_timeexceed_time }, + { &icmp_statistics[0].IcmpOutTimeExcds, &icmp_statistics[0].IcmpInTimeExcds, icmp_unreach, 1 }, /* PARAMETER PROBLEM (12) */ - { &icmp_statistics[0].IcmpOutParmProbs, &icmp_statistics[0].IcmpInParmProbs, icmp_unreach, 1, &sysctl_icmp_paramprob_time }, + { &icmp_statistics[0].IcmpOutParmProbs, &icmp_statistics[0].IcmpInParmProbs, icmp_unreach, 1 }, /* TIMESTAMP (13) */ - { &icmp_statistics[0].IcmpOutTimestamps, &icmp_statistics[0].IcmpInTimestamps, icmp_timestamp, 0, }, + { &icmp_statistics[0].IcmpOutTimestamps, &icmp_statistics[0].IcmpInTimestamps, icmp_timestamp, 0 }, /* TIMESTAMP REPLY (14) */ - { &icmp_statistics[0].IcmpOutTimestampReps, &icmp_statistics[0].IcmpInTimestampReps, icmp_discard, 0, }, + { &icmp_statistics[0].IcmpOutTimestampReps, &icmp_statistics[0].IcmpInTimestampReps, icmp_discard, 0 }, /* INFO (15) */ - { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_discard, 0, }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_discard, 0 }, /* INFO REPLY (16) */ - { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_discard, 0, }, + { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_discard, 0 }, /* ADDR MASK (17) */ - { &icmp_statistics[0].IcmpOutAddrMasks, &icmp_statistics[0].IcmpInAddrMasks, icmp_address, 0, }, + { &icmp_statistics[0].IcmpOutAddrMasks, &icmp_statistics[0].IcmpInAddrMasks, icmp_address, 0 }, /* ADDR MASK REPLY (18) */ - { &icmp_statistics[0].IcmpOutAddrMaskReps, &icmp_statistics[0].IcmpInAddrMaskReps, icmp_address_reply, 0, } + { &icmp_statistics[0].IcmpOutAddrMaskReps, &icmp_statistics[0].IcmpInAddrMaskReps, icmp_address_reply, 0 } }; void __init icmp_init(struct net_proto_family *ops) diff -ur linux-sane/net/ipv4/sysctl_net_ipv4.c linux/net/ipv4/sysctl_net_ipv4.c --- linux-sane/net/ipv4/sysctl_net_ipv4.c Mon Mar 26 04:14:25 2001 +++ linux/net/ipv4/sysctl_net_ipv4.c Fri Aug 3 12:44:28 2001 @@ -32,10 +32,8 @@ extern int sysctl_ip_dynaddr; /* From icmp.c */ -extern int sysctl_icmp_destunreach_time; -extern int sysctl_icmp_timeexceed_time; -extern int sysctl_icmp_paramprob_time; -extern int sysctl_icmp_echoreply_time; +extern int sysctl_icmp_ratelimit; +extern int sysctl_icmp_ratemask; /* From igmp.c */ extern int sysctl_igmp_max_memberships; @@ -178,14 +176,6 @@ {NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses", &sysctl_icmp_ignore_bogus_error_responses, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_ICMP_DESTUNREACH_RATE, "icmp_destunreach_rate", - &sysctl_icmp_destunreach_time, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_ICMP_TIMEEXCEED_RATE, "icmp_timeexceed_rate", - &sysctl_icmp_timeexceed_time, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_ICMP_PARAMPROB_RATE, "icmp_paramprob_rate", - &sysctl_icmp_paramprob_time, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPV4_ICMP_ECHOREPLY_RATE, "icmp_echoreply_rate", - &sysctl_icmp_echoreply_time, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table}, #ifdef CONFIG_IP_MULTICAST {NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships", @@ -227,6 +217,10 @@ &sysctl_tcp_app_win, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_TCP_ADV_WIN_SCALE, "tcp_adv_win_scale", &sysctl_tcp_adv_win_scale, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_ICMP_RATELIMIT, "icmp_ratelimit", + &sysctl_icmp_ratelimit, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_ICMP_RATEMASK, "icmp_ratemask", + &sysctl_icmp_ratemask, sizeof(int), 0644, NULL, &proc_dointvec}, {0} };