aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <dada1@cosmosbay.com>2007-12-05 02:24:56 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:55:54 -0500
commit259d4e41f3ec25f22169daece42729f597b89f9a (patch)
tree8d3d335b3f16834e6374a125f449db383306961d /net
parentd3c5ee6d545b5372fd525ebe16988a5b6efeceb0 (diff)
[NETFILTER]: x_tables: struct xt_table_info diet
Instead of using a big array of NR_CPUS entries, we can compute the size needed at runtime, using nr_cpu_ids This should save some ram (especially on David's machines where NR_CPUS=4096 : 32 KB can be saved per table, and 64KB for dynamically allocated ones (because of slab/slub alignements) ) In particular, the 'bootstrap' tables are not any more static (in data section) but on stack as their size is now very small. This also should reduce the size used on stack in compat functions (get_info() declares an automatic variable, that could be bigger than kernel stack size for big NR_CPUS) Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/arp_tables.c5
-rw-r--r--net/ipv4/netfilter/ip_tables.c24
-rw-r--r--net/ipv6/netfilter/ip6_tables.c5
-rw-r--r--net/netfilter/x_tables.c2
4 files changed, 14 insertions, 22 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 2909c92ecd99..a21722d5c9fa 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -811,8 +811,7 @@ static int do_replace(void __user *user, unsigned int len)
811 return -ENOPROTOOPT; 811 return -ENOPROTOOPT;
812 812
813 /* overflow check */ 813 /* overflow check */
814 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - 814 if (tmp.size >= INT_MAX / num_possible_cpus())
815 SMP_CACHE_BYTES)
816 return -ENOMEM; 815 return -ENOMEM;
817 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 816 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
818 return -ENOMEM; 817 return -ENOMEM;
@@ -1090,7 +1089,7 @@ int arpt_register_table(struct arpt_table *table,
1090{ 1089{
1091 int ret; 1090 int ret;
1092 struct xt_table_info *newinfo; 1091 struct xt_table_info *newinfo;
1093 static struct xt_table_info bootstrap 1092 struct xt_table_info bootstrap
1094 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1093 = { 0, 0, 0, { 0 }, { 0 }, { } };
1095 void *loc_cpu_entry; 1094 void *loc_cpu_entry;
1096 1095
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index ca23c63ced37..87d369244bd9 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1090,7 +1090,8 @@ compat_calc_match(struct ipt_entry_match *m, int * size)
1090 return 0; 1090 return 0;
1091} 1091}
1092 1092
1093static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info, 1093static int compat_calc_entry(struct ipt_entry *e,
1094 const struct xt_table_info *info,
1094 void *base, struct xt_table_info *newinfo) 1095 void *base, struct xt_table_info *newinfo)
1095{ 1096{
1096 struct ipt_entry_target *t; 1097 struct ipt_entry_target *t;
@@ -1118,22 +1119,17 @@ static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info,
1118 return 0; 1119 return 0;
1119} 1120}
1120 1121
1121static int compat_table_info(struct xt_table_info *info, 1122static int compat_table_info(const struct xt_table_info *info,
1122 struct xt_table_info *newinfo) 1123 struct xt_table_info *newinfo)
1123{ 1124{
1124 void *loc_cpu_entry; 1125 void *loc_cpu_entry;
1125 int i;
1126 1126
1127 if (!newinfo || !info) 1127 if (!newinfo || !info)
1128 return -EINVAL; 1128 return -EINVAL;
1129 1129
1130 memset(newinfo, 0, sizeof(struct xt_table_info)); 1130 /* we dont care about newinfo->entries[] */
1131 newinfo->size = info->size; 1131 memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
1132 newinfo->number = info->number; 1132 newinfo->initial_entries = 0;
1133 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1134 newinfo->hook_entry[i] = info->hook_entry[i];
1135 newinfo->underflow[i] = info->underflow[i];
1136 }
1137 loc_cpu_entry = info->entries[raw_smp_processor_id()]; 1133 loc_cpu_entry = info->entries[raw_smp_processor_id()];
1138 return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size, 1134 return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size,
1139 compat_calc_entry, info, loc_cpu_entry, newinfo); 1135 compat_calc_entry, info, loc_cpu_entry, newinfo);
@@ -1327,8 +1323,7 @@ do_replace(void __user *user, unsigned int len)
1327 return -ENOPROTOOPT; 1323 return -ENOPROTOOPT;
1328 1324
1329 /* overflow check */ 1325 /* overflow check */
1330 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - 1326 if (tmp.size >= INT_MAX / num_possible_cpus())
1331 SMP_CACHE_BYTES)
1332 return -ENOMEM; 1327 return -ENOMEM;
1333 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1328 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1334 return -ENOMEM; 1329 return -ENOMEM;
@@ -1868,8 +1863,7 @@ compat_do_replace(void __user *user, unsigned int len)
1868 return -ENOPROTOOPT; 1863 return -ENOPROTOOPT;
1869 1864
1870 /* overflow check */ 1865 /* overflow check */
1871 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - 1866 if (tmp.size >= INT_MAX / num_possible_cpus())
1872 SMP_CACHE_BYTES)
1873 return -ENOMEM; 1867 return -ENOMEM;
1874 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1868 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1875 return -ENOMEM; 1869 return -ENOMEM;
@@ -2126,7 +2120,7 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
2126{ 2120{
2127 int ret; 2121 int ret;
2128 struct xt_table_info *newinfo; 2122 struct xt_table_info *newinfo;
2129 static struct xt_table_info bootstrap 2123 struct xt_table_info bootstrap
2130 = { 0, 0, 0, { 0 }, { 0 }, { } }; 2124 = { 0, 0, 0, { 0 }, { 0 }, { } };
2131 void *loc_cpu_entry; 2125 void *loc_cpu_entry;
2132 2126
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index e1e87eff4686..e60c1b4b1ec8 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1042,8 +1042,7 @@ do_replace(void __user *user, unsigned int len)
1042 return -EFAULT; 1042 return -EFAULT;
1043 1043
1044 /* overflow check */ 1044 /* overflow check */
1045 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - 1045 if (tmp.size >= INT_MAX / num_possible_cpus())
1046 SMP_CACHE_BYTES)
1047 return -ENOMEM; 1046 return -ENOMEM;
1048 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1047 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1049 return -ENOMEM; 1048 return -ENOMEM;
@@ -1339,7 +1338,7 @@ int ip6t_register_table(struct xt_table *table,
1339{ 1338{
1340 int ret; 1339 int ret;
1341 struct xt_table_info *newinfo; 1340 struct xt_table_info *newinfo;
1342 static struct xt_table_info bootstrap 1341 struct xt_table_info bootstrap
1343 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1342 = { 0, 0, 0, { 0 }, { 0 }, { } };
1344 void *loc_cpu_entry; 1343 void *loc_cpu_entry;
1345 1344
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index b6160e41eb1c..07bb465d9518 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -499,7 +499,7 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)
499 if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages) 499 if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages)
500 return NULL; 500 return NULL;
501 501
502 newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL); 502 newinfo = kzalloc(XT_TABLE_INFO_SZ, GFP_KERNEL);
503 if (!newinfo) 503 if (!newinfo)
504 return NULL; 504 return NULL;
505 505