aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2010-01-04 10:28:38 -0500
committerPatrick McHardy <kaber@trash.net>2010-01-04 10:28:38 -0500
commit294188ae32f984a072c64c959354b2f6f52f80a7 (patch)
tree87e15911eebc0ef54375afc01aef3fd5efadd9c7
parent5191d50192ec1281e51cbcb5248cb2667ff4d896 (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.c17
-rw-r--r--net/netfilter/xt_recent.c20
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
43static u_int32_t connlimit_rnd; 43static u_int32_t connlimit_rnd __read_mostly;
44static bool connlimit_rnd_inited; 44static bool connlimit_rnd_inited __read_mostly;
45 45
46static inline unsigned int connlimit_iphash(__be32 addr) 46static 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;
90static const struct file_operations recent_old_fops, recent_mt_fops; 90static const struct file_operations recent_old_fops, recent_mt_fops;
91#endif 91#endif
92 92
93static u_int32_t hash_rnd; 93static u_int32_t hash_rnd __read_mostly;
94static bool hash_rnd_initted; 94static bool hash_rnd_inited __read_mostly;
95 95
96static unsigned int recent_entry_hash4(const union nf_inet_addr *addr) 96static 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
106static unsigned int recent_entry_hash6(const union nf_inet_addr *addr) 102static 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)