2 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2013 Pablo Neira Ayuso <pablo@netfilter.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/netfilter_bridge.h>
15 #include <net/netfilter/nf_tables.h>
17 #include <linux/ipv6.h>
18 #include <net/netfilter/nf_tables_ipv4.h>
19 #include <net/netfilter/nf_tables_ipv6.h>
22 nft_do_chain_bridge(void *priv
,
24 const struct nf_hook_state
*state
)
26 struct nft_pktinfo pkt
;
28 switch (eth_hdr(skb
)->h_proto
) {
30 nft_set_pktinfo_ipv4_validate(&pkt
, skb
, state
);
32 case htons(ETH_P_IPV6
):
33 nft_set_pktinfo_ipv6_validate(&pkt
, skb
, state
);
36 nft_set_pktinfo_unspec(&pkt
, skb
, state
);
40 return nft_do_chain(&pkt
, priv
);
43 static struct nft_af_info nft_af_bridge __read_mostly
= {
44 .family
= NFPROTO_BRIDGE
,
45 .nhooks
= NF_BR_NUMHOOKS
,
49 [NF_BR_PRE_ROUTING
] = nft_do_chain_bridge
,
50 [NF_BR_LOCAL_IN
] = nft_do_chain_bridge
,
51 [NF_BR_FORWARD
] = nft_do_chain_bridge
,
52 [NF_BR_LOCAL_OUT
] = nft_do_chain_bridge
,
53 [NF_BR_POST_ROUTING
] = nft_do_chain_bridge
,
57 static int nf_tables_bridge_init_net(struct net
*net
)
59 net
->nft
.bridge
= kmalloc(sizeof(struct nft_af_info
), GFP_KERNEL
);
60 if (net
->nft
.bridge
== NULL
)
63 memcpy(net
->nft
.bridge
, &nft_af_bridge
, sizeof(nft_af_bridge
));
65 if (nft_register_afinfo(net
, net
->nft
.bridge
) < 0)
70 kfree(net
->nft
.bridge
);
74 static void nf_tables_bridge_exit_net(struct net
*net
)
76 nft_unregister_afinfo(net
, net
->nft
.bridge
);
77 kfree(net
->nft
.bridge
);
80 static struct pernet_operations nf_tables_bridge_net_ops
= {
81 .init
= nf_tables_bridge_init_net
,
82 .exit
= nf_tables_bridge_exit_net
,
85 static const struct nf_chain_type filter_bridge
= {
87 .type
= NFT_CHAIN_T_DEFAULT
,
88 .family
= NFPROTO_BRIDGE
,
90 .hook_mask
= (1 << NF_BR_PRE_ROUTING
) |
91 (1 << NF_BR_LOCAL_IN
) |
92 (1 << NF_BR_FORWARD
) |
93 (1 << NF_BR_LOCAL_OUT
) |
94 (1 << NF_BR_POST_ROUTING
),
97 static void nf_br_saveroute(const struct sk_buff
*skb
,
98 struct nf_queue_entry
*entry
)
102 static int nf_br_reroute(struct net
*net
, struct sk_buff
*skb
,
103 const struct nf_queue_entry
*entry
)
108 static __sum16
nf_br_checksum(struct sk_buff
*skb
, unsigned int hook
,
109 unsigned int dataoff
, u_int8_t protocol
)
114 static __sum16
nf_br_checksum_partial(struct sk_buff
*skb
, unsigned int hook
,
115 unsigned int dataoff
, unsigned int len
,
121 static int nf_br_route(struct net
*net
, struct dst_entry
**dst
,
122 struct flowi
*fl
, bool strict __always_unused
)
127 static const struct nf_afinfo nf_br_afinfo
= {
129 .checksum
= nf_br_checksum
,
130 .checksum_partial
= nf_br_checksum_partial
,
131 .route
= nf_br_route
,
132 .saveroute
= nf_br_saveroute
,
133 .reroute
= nf_br_reroute
,
137 static int __init
nf_tables_bridge_init(void)
141 nf_register_afinfo(&nf_br_afinfo
);
142 ret
= nft_register_chain_type(&filter_bridge
);
146 ret
= register_pernet_subsys(&nf_tables_bridge_net_ops
);
153 nft_unregister_chain_type(&filter_bridge
);
155 nf_unregister_afinfo(&nf_br_afinfo
);
159 static void __exit
nf_tables_bridge_exit(void)
161 unregister_pernet_subsys(&nf_tables_bridge_net_ops
);
162 nft_unregister_chain_type(&filter_bridge
);
163 nf_unregister_afinfo(&nf_br_afinfo
);
166 module_init(nf_tables_bridge_init
);
167 module_exit(nf_tables_bridge_exit
);
169 MODULE_LICENSE("GPL");
170 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
171 MODULE_ALIAS_NFT_FAMILY(AF_BRIDGE
);