diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-01-04 10:28:38 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-01-04 10:28:38 -0500 |
commit | 294188ae32f984a072c64c959354b2f6f52f80a7 (patch) | |
tree | 87e15911eebc0ef54375afc01aef3fd5efadd9c7 | |
parent | 5191d50192ec1281e51cbcb5248cb2667ff4d896 (diff) |
netfilter: xtables: obtain random bytes earlier, in checkentry
We can initialize the random hash bytes on checkentry. This is
preferable since it is outside the hot path.
Reference: http://bugzilla.netfilter.org/show_bug.cgi?id=621
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | net/netfilter/xt_connlimit.c | 17 | ||||
-rw-r--r-- | net/netfilter/xt_recent.c | 20 |
2 files changed, 14 insertions, 23 deletions
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 38f03f75a636..8103bef78e44 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c | |||
@@ -40,15 +40,11 @@ struct xt_connlimit_data { | |||
40 | spinlock_t lock; | 40 | spinlock_t lock; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static u_int32_t connlimit_rnd; | 43 | static u_int32_t connlimit_rnd __read_mostly; |
44 | static bool connlimit_rnd_inited; | 44 | static bool connlimit_rnd_inited __read_mostly; |
45 | 45 | ||
46 | static inline unsigned int connlimit_iphash(__be32 addr) | 46 | static inline unsigned int connlimit_iphash(__be32 addr) |
47 | { | 47 | { |
48 | if (unlikely(!connlimit_rnd_inited)) { | ||
49 | get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd)); | ||
50 | connlimit_rnd_inited = true; | ||
51 | } | ||
52 | return jhash_1word((__force __u32)addr, connlimit_rnd) & 0xFF; | 48 | return jhash_1word((__force __u32)addr, connlimit_rnd) & 0xFF; |
53 | } | 49 | } |
54 | 50 | ||
@@ -59,11 +55,6 @@ connlimit_iphash6(const union nf_inet_addr *addr, | |||
59 | union nf_inet_addr res; | 55 | union nf_inet_addr res; |
60 | unsigned int i; | 56 | unsigned int i; |
61 | 57 | ||
62 | if (unlikely(!connlimit_rnd_inited)) { | ||
63 | get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd)); | ||
64 | connlimit_rnd_inited = true; | ||
65 | } | ||
66 | |||
67 | for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i) | 58 | for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i) |
68 | res.ip6[i] = addr->ip6[i] & mask->ip6[i]; | 59 | res.ip6[i] = addr->ip6[i] & mask->ip6[i]; |
69 | 60 | ||
@@ -226,6 +217,10 @@ static bool connlimit_mt_check(const struct xt_mtchk_param *par) | |||
226 | struct xt_connlimit_info *info = par->matchinfo; | 217 | struct xt_connlimit_info *info = par->matchinfo; |
227 | unsigned int i; | 218 | unsigned int i; |
228 | 219 | ||
220 | if (unlikely(!connlimit_rnd_inited)) { | ||
221 | get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd)); | ||
222 | connlimit_rnd_inited = true; | ||
223 | } | ||
229 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 224 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { |
230 | printk(KERN_WARNING "cannot load conntrack support for " | 225 | printk(KERN_WARNING "cannot load conntrack support for " |
231 | "address family %u\n", par->family); | 226 | "address family %u\n", par->family); |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index fc70a49c0afd..768d01ff1fea 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -90,25 +90,17 @@ static struct proc_dir_entry *recent_proc_dir; | |||
90 | static const struct file_operations recent_old_fops, recent_mt_fops; | 90 | static const struct file_operations recent_old_fops, recent_mt_fops; |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | static u_int32_t hash_rnd; | 93 | static u_int32_t hash_rnd __read_mostly; |
94 | static bool hash_rnd_initted; | 94 | static bool hash_rnd_inited __read_mostly; |
95 | 95 | ||
96 | static unsigned int recent_entry_hash4(const union nf_inet_addr *addr) | 96 | static inline unsigned int recent_entry_hash4(const union nf_inet_addr *addr) |
97 | { | 97 | { |
98 | if (!hash_rnd_initted) { | ||
99 | get_random_bytes(&hash_rnd, sizeof(hash_rnd)); | ||
100 | hash_rnd_initted = true; | ||
101 | } | ||
102 | return jhash_1word((__force u32)addr->ip, hash_rnd) & | 98 | return jhash_1word((__force u32)addr->ip, hash_rnd) & |
103 | (ip_list_hash_size - 1); | 99 | (ip_list_hash_size - 1); |
104 | } | 100 | } |
105 | 101 | ||
106 | static unsigned int recent_entry_hash6(const union nf_inet_addr *addr) | 102 | static inline unsigned int recent_entry_hash6(const union nf_inet_addr *addr) |
107 | { | 103 | { |
108 | if (!hash_rnd_initted) { | ||
109 | get_random_bytes(&hash_rnd, sizeof(hash_rnd)); | ||
110 | hash_rnd_initted = true; | ||
111 | } | ||
112 | return jhash2((u32 *)addr->ip6, ARRAY_SIZE(addr->ip6), hash_rnd) & | 104 | return jhash2((u32 *)addr->ip6, ARRAY_SIZE(addr->ip6), hash_rnd) & |
113 | (ip_list_hash_size - 1); | 105 | (ip_list_hash_size - 1); |
114 | } | 106 | } |
@@ -287,6 +279,10 @@ static bool recent_mt_check(const struct xt_mtchk_param *par) | |||
287 | unsigned i; | 279 | unsigned i; |
288 | bool ret = false; | 280 | bool ret = false; |
289 | 281 | ||
282 | if (unlikely(!hash_rnd_inited)) { | ||
283 | get_random_bytes(&hash_rnd, sizeof(hash_rnd)); | ||
284 | hash_rnd_inited = true; | ||
285 | } | ||
290 | if (hweight8(info->check_set & | 286 | if (hweight8(info->check_set & |
291 | (XT_RECENT_SET | XT_RECENT_REMOVE | | 287 | (XT_RECENT_SET | XT_RECENT_REMOVE | |
292 | XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1) | 288 | XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1) |