11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *  ebtable_filter
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *	Authors:
51da177e4SLinus Torvalds  *	Bart De Schuymer <bdschuym@pandora.be>
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *  April, 2002
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include <linux/netfilter_bridge/ebtables.h>
121da177e4SLinus Torvalds #include <linux/module.h>
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \
151da177e4SLinus Torvalds    (1 << NF_BR_LOCAL_OUT))
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds static struct ebt_entries initial_chains[] =
181da177e4SLinus Torvalds {
191da177e4SLinus Torvalds 	{
201da177e4SLinus Torvalds 		.name	= "INPUT",
211da177e4SLinus Torvalds 		.policy	= EBT_ACCEPT,
221da177e4SLinus Torvalds 	},
231da177e4SLinus Torvalds 	{
241da177e4SLinus Torvalds 		.name	= "FORWARD",
251da177e4SLinus Torvalds 		.policy	= EBT_ACCEPT,
261da177e4SLinus Torvalds 	},
271da177e4SLinus Torvalds 	{
281da177e4SLinus Torvalds 		.name	= "OUTPUT",
291da177e4SLinus Torvalds 		.policy	= EBT_ACCEPT,
301da177e4SLinus Torvalds 	},
311da177e4SLinus Torvalds };
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds static struct ebt_replace initial_table =
341da177e4SLinus Torvalds {
351da177e4SLinus Torvalds 	.name		= "filter",
361da177e4SLinus Torvalds 	.valid_hooks	= FILTER_VALID_HOOKS,
371da177e4SLinus Torvalds 	.entries_size	= 3 * sizeof(struct ebt_entries),
381da177e4SLinus Torvalds 	.hook_entry	= {
391da177e4SLinus Torvalds 		[NF_BR_LOCAL_IN]	= &initial_chains[0],
401da177e4SLinus Torvalds 		[NF_BR_FORWARD]		= &initial_chains[1],
411da177e4SLinus Torvalds 		[NF_BR_LOCAL_OUT]	= &initial_chains[2],
421da177e4SLinus Torvalds 	},
431da177e4SLinus Torvalds 	.entries	= (char *)initial_chains,
441da177e4SLinus Torvalds };
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
471da177e4SLinus Torvalds {
481da177e4SLinus Torvalds 	if (valid_hooks & ~FILTER_VALID_HOOKS)
491da177e4SLinus Torvalds 		return -EINVAL;
501da177e4SLinus Torvalds 	return 0;
511da177e4SLinus Torvalds }
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds static struct ebt_table frame_filter =
541da177e4SLinus Torvalds {
551da177e4SLinus Torvalds 	.name		= "filter",
561da177e4SLinus Torvalds 	.table		= &initial_table,
571da177e4SLinus Torvalds 	.valid_hooks	= FILTER_VALID_HOOKS,
581da177e4SLinus Torvalds 	.lock		= RW_LOCK_UNLOCKED,
591da177e4SLinus Torvalds 	.check		= check,
601da177e4SLinus Torvalds 	.me		= THIS_MODULE,
611da177e4SLinus Torvalds };
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds static unsigned int
641da177e4SLinus Torvalds ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
651da177e4SLinus Torvalds    const struct net_device *out, int (*okfn)(struct sk_buff *))
661da177e4SLinus Torvalds {
671da177e4SLinus Torvalds 	return ebt_do_table(hook, pskb, in, out, &frame_filter);
681da177e4SLinus Torvalds }
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds static struct nf_hook_ops ebt_ops_filter[] = {
711da177e4SLinus Torvalds 	{
721da177e4SLinus Torvalds 		.hook		= ebt_hook,
731da177e4SLinus Torvalds 		.owner		= THIS_MODULE,
741da177e4SLinus Torvalds 		.pf		= PF_BRIDGE,
751da177e4SLinus Torvalds 		.hooknum	= NF_BR_LOCAL_IN,
761da177e4SLinus Torvalds 		.priority	= NF_BR_PRI_FILTER_BRIDGED,
771da177e4SLinus Torvalds 	},
781da177e4SLinus Torvalds 	{
791da177e4SLinus Torvalds 		.hook		= ebt_hook,
801da177e4SLinus Torvalds 		.owner		= THIS_MODULE,
811da177e4SLinus Torvalds 		.pf		= PF_BRIDGE,
821da177e4SLinus Torvalds 		.hooknum	= NF_BR_FORWARD,
831da177e4SLinus Torvalds 		.priority	= NF_BR_PRI_FILTER_BRIDGED,
841da177e4SLinus Torvalds 	},
851da177e4SLinus Torvalds 	{
861da177e4SLinus Torvalds 		.hook		= ebt_hook,
871da177e4SLinus Torvalds 		.owner		= THIS_MODULE,
881da177e4SLinus Torvalds 		.pf		= PF_BRIDGE,
891da177e4SLinus Torvalds 		.hooknum	= NF_BR_LOCAL_OUT,
901da177e4SLinus Torvalds 		.priority	= NF_BR_PRI_FILTER_OTHER,
911da177e4SLinus Torvalds 	},
921da177e4SLinus Torvalds };
931da177e4SLinus Torvalds 
9465b4b4e8SAndrew Morton static int __init ebtable_filter_init(void)
951da177e4SLinus Torvalds {
961da177e4SLinus Torvalds 	int i, j, ret;
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds 	ret = ebt_register_table(&frame_filter);
991da177e4SLinus Torvalds 	if (ret < 0)
1001da177e4SLinus Torvalds 		return ret;
1011da177e4SLinus Torvalds 	for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++)
1021da177e4SLinus Torvalds 		if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0)
1031da177e4SLinus Torvalds 			goto cleanup;
1041da177e4SLinus Torvalds 	return ret;
1051da177e4SLinus Torvalds cleanup:
1061da177e4SLinus Torvalds 	for (j = 0; j < i; j++)
1071da177e4SLinus Torvalds 		nf_unregister_hook(&ebt_ops_filter[j]);
1081da177e4SLinus Torvalds 	ebt_unregister_table(&frame_filter);
1091da177e4SLinus Torvalds 	return ret;
1101da177e4SLinus Torvalds }
1111da177e4SLinus Torvalds 
11265b4b4e8SAndrew Morton static void __exit ebtable_filter_fini(void)
1131da177e4SLinus Torvalds {
1141da177e4SLinus Torvalds 	int i;
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds 	for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++)
1171da177e4SLinus Torvalds 		nf_unregister_hook(&ebt_ops_filter[i]);
1181da177e4SLinus Torvalds 	ebt_unregister_table(&frame_filter);
1191da177e4SLinus Torvalds }
1201da177e4SLinus Torvalds 
12165b4b4e8SAndrew Morton module_init(ebtable_filter_init);
12265b4b4e8SAndrew Morton module_exit(ebtable_filter_fini);
1231da177e4SLinus Torvalds MODULE_LICENSE("GPL");
124