1/*
2 *  ebtable_filter
3 *
4 *	Authors:
5 *	Bart De Schuymer <bdschuym@pandora.be>
6 *
7 *  April, 2002
8 *
9 */
10
11#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/module.h>
13
14#define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \
15   (1 << NF_BR_LOCAL_OUT))
16
17static struct ebt_entries initial_chains[] =
18{
19	{
20		.name	= "INPUT",
21		.policy	= EBT_ACCEPT,
22	},
23	{
24		.name	= "FORWARD",
25		.policy	= EBT_ACCEPT,
26	},
27	{
28		.name	= "OUTPUT",
29		.policy	= EBT_ACCEPT,
30	},
31};
32
33static struct ebt_replace_kernel initial_table =
34{
35	.name		= "filter",
36	.valid_hooks	= FILTER_VALID_HOOKS,
37	.entries_size	= 3 * sizeof(struct ebt_entries),
38	.hook_entry	= {
39		[NF_BR_LOCAL_IN]	= &initial_chains[0],
40		[NF_BR_FORWARD]		= &initial_chains[1],
41		[NF_BR_LOCAL_OUT]	= &initial_chains[2],
42	},
43	.entries	= (char *)initial_chains,
44};
45
46static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
47{
48	if (valid_hooks & ~FILTER_VALID_HOOKS)
49		return -EINVAL;
50	return 0;
51}
52
53static struct ebt_table frame_filter =
54{
55	.name		= "filter",
56	.table		= &initial_table,
57	.valid_hooks	= FILTER_VALID_HOOKS,
58	.lock		= RW_LOCK_UNLOCKED,
59	.check		= check,
60	.me		= THIS_MODULE,
61};
62
63static unsigned int
64ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
65   const struct net_device *out, int (*okfn)(struct sk_buff *))
66{
67	return ebt_do_table(hook, pskb, in, out, &frame_filter);
68}
69
70static struct nf_hook_ops ebt_ops_filter[] = {
71	{
72		.hook		= ebt_hook,
73		.owner		= THIS_MODULE,
74		.pf		= PF_BRIDGE,
75		.hooknum	= NF_BR_LOCAL_IN,
76		.priority	= NF_BR_PRI_FILTER_BRIDGED,
77	},
78	{
79		.hook		= ebt_hook,
80		.owner		= THIS_MODULE,
81		.pf		= PF_BRIDGE,
82		.hooknum	= NF_BR_FORWARD,
83		.priority	= NF_BR_PRI_FILTER_BRIDGED,
84	},
85	{
86		.hook		= ebt_hook,
87		.owner		= THIS_MODULE,
88		.pf		= PF_BRIDGE,
89		.hooknum	= NF_BR_LOCAL_OUT,
90		.priority	= NF_BR_PRI_FILTER_OTHER,
91	},
92};
93
94static int __init ebtable_filter_init(void)
95{
96	int i, j, ret;
97
98	ret = ebt_register_table(&frame_filter);
99	if (ret < 0)
100		return ret;
101	for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++)
102		if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0)
103			goto cleanup;
104	return ret;
105cleanup:
106	for (j = 0; j < i; j++)
107		nf_unregister_hook(&ebt_ops_filter[j]);
108	ebt_unregister_table(&frame_filter);
109	return ret;
110}
111
112static void __exit ebtable_filter_fini(void)
113{
114	int i;
115
116	for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++)
117		nf_unregister_hook(&ebt_ops_filter[i]);
118	ebt_unregister_table(&frame_filter);
119}
120
121module_init(ebtable_filter_init);
122module_exit(ebtable_filter_fini);
123MODULE_LICENSE("GPL");
124