Jan Engelhardt wrote: > The static initial tables are pretty large, and after the net > namespace has been instantiated, they just hang around for nothing. > This commit removes them and creates tables on-demand at runtime when > needed. > > Some numbers: > text data bss dec hex filename > -4043674 563169 512000 5118843 4e1b7b ./vmlinux[x86_64](before) > +4045071 550177 512000 5107248 4dee30 ./vmlinux[x86_64](after) > = +1397 -12992 > === -11595 They are actually freed when no network namespaces are used. But I agree that this makes sense since distributors are going to enable them. > +/* > + * Today's hack: quantum tunneling in structs > + * > + * 'entries' and 'term' are never anywhere referenced by word in code. In fact, > + * they serve as the hanging-off data accessed through repl.data[]! > + */ > +#define xt_repldata_mk(type, typ2) \ > + struct { \ > + struct type##_replace repl; \ > + struct type##_standard entries[nhooks]; \ > + struct type##_error term; \ > + } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \ > + if (tbl == NULL) \ > + return NULL; \ > + strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \ > + tbl->term = (struct type##_error)typ2##_ERROR_INIT; \ > + tbl->repl.valid_hooks = hook_mask; \ > + tbl->repl.num_entries = nhooks + 1; \ > + tbl->repl.size = nhooks * sizeof(struct type##_standard) + \ > + sizeof(struct type##_error); \ > + for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \ > + if (!(hook_mask & 1)) \ > + continue; \ > + tbl->repl.hook_entry[hooknum] = bytes; \ > + tbl->repl.underflow[hooknum] = bytes; \ > + tbl->entries[i++] = (struct type##_standard) \ > + typ2##_STANDARD_INIT(NF_ACCEPT); \ > + bytes += sizeof(struct type##_standard); \ > + } > + > +void *xt_repldata_create(const struct xt_table *info) > +{ > + unsigned int hook_mask = info->valid_hooks; > + unsigned int nhooks = xt_hookmask_bitcount(hook_mask); > + unsigned int bytes = 0, hooknum = 0, i = 0; > + > + if (info->af == NFPROTO_IPV6) { > + xt_repldata_mk(ip6t, IP6T); > + return tbl; Would look slightly nicer if the above macro would "return" the table, then you could simply do "return xt_repldata_mk(..);" without using variables declared within the macro. > + } else if (info->af == NFPROTO_IPV4) { > + xt_repldata_mk(ipt, IPT); > + return tbl; > + } else if (info->af == NFPROTO_ARP) { > + xt_repldata_mk(arpt, ARPT); > + return tbl; > + } > + return NULL; > +} > +EXPORT_SYMBOL_GPL(xt_repldata_create); How about adding this beauty to the respective address-family specific files (ip_tables.c etc)? That would avoid some of the bloat of the new function (apparently almost 1300bytes) when only some of those modules are used. I also would prefer a nicer name, something like xt_alloc_initial_table(). -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html