1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * ebtable_filter |
4 | * |
5 | * Authors: |
6 | * Bart De Schuymer <bdschuym@pandora.be> |
7 | * |
8 | * April, 2002 |
9 | * |
10 | */ |
11 | |
12 | #include <linux/netfilter_bridge/ebtables.h> |
13 | #include <uapi/linux/netfilter_bridge.h> |
14 | #include <linux/module.h> |
15 | |
16 | #define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ |
17 | (1 << NF_BR_LOCAL_OUT)) |
18 | |
19 | static struct ebt_entries initial_chains[] = { |
20 | { |
21 | .name = "INPUT" , |
22 | .policy = EBT_ACCEPT, |
23 | }, |
24 | { |
25 | .name = "FORWARD" , |
26 | .policy = EBT_ACCEPT, |
27 | }, |
28 | { |
29 | .name = "OUTPUT" , |
30 | .policy = EBT_ACCEPT, |
31 | }, |
32 | }; |
33 | |
34 | static struct ebt_replace_kernel initial_table = { |
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 | |
46 | static const struct ebt_table frame_filter = { |
47 | .name = "filter" , |
48 | .table = &initial_table, |
49 | .valid_hooks = FILTER_VALID_HOOKS, |
50 | .me = THIS_MODULE, |
51 | }; |
52 | |
53 | static const struct nf_hook_ops ebt_ops_filter[] = { |
54 | { |
55 | .hook = ebt_do_table, |
56 | .pf = NFPROTO_BRIDGE, |
57 | .hooknum = NF_BR_LOCAL_IN, |
58 | .priority = NF_BR_PRI_FILTER_BRIDGED, |
59 | }, |
60 | { |
61 | .hook = ebt_do_table, |
62 | .pf = NFPROTO_BRIDGE, |
63 | .hooknum = NF_BR_FORWARD, |
64 | .priority = NF_BR_PRI_FILTER_BRIDGED, |
65 | }, |
66 | { |
67 | .hook = ebt_do_table, |
68 | .pf = NFPROTO_BRIDGE, |
69 | .hooknum = NF_BR_LOCAL_OUT, |
70 | .priority = NF_BR_PRI_FILTER_OTHER, |
71 | }, |
72 | }; |
73 | |
74 | static int frame_filter_table_init(struct net *net) |
75 | { |
76 | return ebt_register_table(net, table: &frame_filter, ops: ebt_ops_filter); |
77 | } |
78 | |
79 | static void __net_exit frame_filter_net_pre_exit(struct net *net) |
80 | { |
81 | ebt_unregister_table_pre_exit(net, tablename: "filter" ); |
82 | } |
83 | |
84 | static void __net_exit frame_filter_net_exit(struct net *net) |
85 | { |
86 | ebt_unregister_table(net, tablename: "filter" ); |
87 | } |
88 | |
89 | static struct pernet_operations frame_filter_net_ops = { |
90 | .exit = frame_filter_net_exit, |
91 | .pre_exit = frame_filter_net_pre_exit, |
92 | }; |
93 | |
94 | static int __init ebtable_filter_init(void) |
95 | { |
96 | int ret = ebt_register_template(t: &frame_filter, table_init: frame_filter_table_init); |
97 | |
98 | if (ret) |
99 | return ret; |
100 | |
101 | ret = register_pernet_subsys(&frame_filter_net_ops); |
102 | if (ret) { |
103 | ebt_unregister_template(t: &frame_filter); |
104 | return ret; |
105 | } |
106 | |
107 | return 0; |
108 | } |
109 | |
110 | static void __exit ebtable_filter_fini(void) |
111 | { |
112 | unregister_pernet_subsys(&frame_filter_net_ops); |
113 | ebt_unregister_template(t: &frame_filter); |
114 | } |
115 | |
116 | module_init(ebtable_filter_init); |
117 | module_exit(ebtable_filter_fini); |
118 | MODULE_LICENSE("GPL" ); |
119 | MODULE_DESCRIPTION("ebtables legacy filter table" ); |
120 | |