Commit 353131f3 authored by Andrew Morton's avatar Andrew Morton Committed by Hideaki Yoshifuji

[NET]: Simply net_ratelimit().

Reimplement net_ratelimit() in terms of the new printk_ratelimit().

As net_ratelimit() already has it own sysctls we generalise
printk_ratelimit() a bit so that networking does not lose its existing
sysctls and so that it can use different time constants from the more generic
printk_ratelimit().
parent f8c11435
...@@ -90,6 +90,7 @@ asmlinkage int printk(const char * fmt, ...) ...@@ -90,6 +90,7 @@ asmlinkage int printk(const char * fmt, ...)
unsigned long int_sqrt(unsigned long); unsigned long int_sqrt(unsigned long);
extern int printk_ratelimit(void); extern int printk_ratelimit(void);
extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst);
static inline void console_silent(void) static inline void console_silent(void)
{ {
......
...@@ -784,12 +784,6 @@ void tty_write_message(struct tty_struct *tty, char *msg) ...@@ -784,12 +784,6 @@ void tty_write_message(struct tty_struct *tty, char *msg)
return; return;
} }
/* minimum time in jiffies between messages */
int printk_ratelimit_jiffies = 5*HZ;
/* number of messages we send before ratelimiting */
int printk_ratelimit_burst = 10;
/* /*
* printk rate limiting, lifted from the networking subsystem. * printk rate limiting, lifted from the networking subsystem.
* *
...@@ -797,7 +791,7 @@ int printk_ratelimit_burst = 10; ...@@ -797,7 +791,7 @@ int printk_ratelimit_burst = 10;
* every printk_ratelimit_jiffies to make a denial-of-service * every printk_ratelimit_jiffies to make a denial-of-service
* attack impossible. * attack impossible.
*/ */
int printk_ratelimit(void) int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
{ {
static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED; static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
static unsigned long toks = 10*5*HZ; static unsigned long toks = 10*5*HZ;
...@@ -809,12 +803,12 @@ int printk_ratelimit(void) ...@@ -809,12 +803,12 @@ int printk_ratelimit(void)
spin_lock_irqsave(&ratelimit_lock, flags); spin_lock_irqsave(&ratelimit_lock, flags);
toks += now - last_msg; toks += now - last_msg;
last_msg = now; last_msg = now;
if (toks > (printk_ratelimit_burst * printk_ratelimit_jiffies)) if (toks > (ratelimit_burst * ratelimit_jiffies))
toks = printk_ratelimit_burst * printk_ratelimit_jiffies; toks = ratelimit_burst * ratelimit_jiffies;
if (toks >= printk_ratelimit_jiffies) { if (toks >= ratelimit_jiffies) {
int lost = missed; int lost = missed;
missed = 0; missed = 0;
toks -= printk_ratelimit_jiffies; toks -= ratelimit_jiffies;
spin_unlock_irqrestore(&ratelimit_lock, flags); spin_unlock_irqrestore(&ratelimit_lock, flags);
if (lost) if (lost)
printk(KERN_WARNING "printk: %d messages suppressed.\n", lost); printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
...@@ -824,4 +818,17 @@ int printk_ratelimit(void) ...@@ -824,4 +818,17 @@ int printk_ratelimit(void)
spin_unlock_irqrestore(&ratelimit_lock, flags); spin_unlock_irqrestore(&ratelimit_lock, flags);
return 0; return 0;
} }
EXPORT_SYMBOL(__printk_ratelimit);
/* minimum time in jiffies between messages */
int printk_ratelimit_jiffies = 5*HZ;
/* number of messages we send before ratelimiting */
int printk_ratelimit_burst = 10;
int printk_ratelimit(void)
{
return __printk_ratelimit(printk_ratelimit_jiffies,
printk_ratelimit_burst);
}
EXPORT_SYMBOL(printk_ratelimit); EXPORT_SYMBOL(printk_ratelimit);
...@@ -41,37 +41,11 @@ int net_msg_cost = 5*HZ; ...@@ -41,37 +41,11 @@ int net_msg_cost = 5*HZ;
int net_msg_burst = 10; int net_msg_burst = 10;
/* /*
* This enforces a rate limit: not more than one kernel message * All net warning printk()s should be guarded by this function.
* every 5secs to make a denial-of-service attack impossible.
*
* All warning printk()s should be guarded by this function.
*/ */
int net_ratelimit(void) int net_ratelimit(void)
{ {
static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED; return __printk_ratelimit(net_msg_cost, net_msg_burst);
static unsigned long toks = 10*5*HZ;
static unsigned long last_msg;
static int missed;
unsigned long flags;
unsigned long now = jiffies;
spin_lock_irqsave(&ratelimit_lock, flags);
toks += now - last_msg;
last_msg = now;
if (toks > net_msg_burst)
toks = net_msg_burst;
if (toks >= net_msg_cost) {
int lost = missed;
missed = 0;
toks -= net_msg_cost;
spin_unlock_irqrestore(&ratelimit_lock, flags);
if (lost)
printk(KERN_WARNING "NET: %d messages suppressed.\n", lost);
return 1;
}
missed++;
spin_unlock_irqrestore(&ratelimit_lock, flags);
return 0;
} }
EXPORT_SYMBOL(net_random); EXPORT_SYMBOL(net_random);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment