1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef __LINUX_BRIDGE_NETFILTER_H
31da177e4SLinus Torvalds #define __LINUX_BRIDGE_NETFILTER_H
41da177e4SLinus Torvalds 
5607ca46eSDavid Howells #include <uapi/linux/netfilter_bridge.h>
6c737b7c4SFlorian Westphal #include <linux/skbuff.h>
71da177e4SLinus Torvalds 
846705b07SJeremy Sowden struct nf_bridge_frag_data {
946705b07SJeremy Sowden 	char    mac[ETH_HLEN];
1046705b07SJeremy Sowden 	bool    vlan_present;
1146705b07SJeremy Sowden 	u16     vlan_tci;
1246705b07SJeremy Sowden 	__be16  vlan_proto;
1346705b07SJeremy Sowden };
1446705b07SJeremy Sowden 
1534666d46SPablo Neira Ayuso #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
161da177e4SLinus Torvalds 
170c4b51f0SEric W. Biederman int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
18ea2d9b41SBart De Schuymer 
br_drop_fake_rtable(struct sk_buff * skb)19a881e963SPeter Huang (Peng) static inline void br_drop_fake_rtable(struct sk_buff *skb)
20a881e963SPeter Huang (Peng) {
21a881e963SPeter Huang (Peng) 	struct dst_entry *dst = skb_dst(skb);
22a881e963SPeter Huang (Peng) 
23a881e963SPeter Huang (Peng) 	if (dst && (dst->flags & DST_FAKE_RTABLE))
24a881e963SPeter Huang (Peng) 		skb_dst_drop(skb);
25a881e963SPeter Huang (Peng) }
26a881e963SPeter Huang (Peng) 
27c4b0e771SFlorian Westphal static inline struct nf_bridge_info *
nf_bridge_info_get(const struct sk_buff * skb)28c4b0e771SFlorian Westphal nf_bridge_info_get(const struct sk_buff *skb)
29c4b0e771SFlorian Westphal {
30de8bda1dSFlorian Westphal 	return skb_ext_find(skb, SKB_EXT_BRIDGE_NF);
31c4b0e771SFlorian Westphal }
32c4b0e771SFlorian Westphal 
nf_bridge_info_exists(const struct sk_buff * skb)33c4b0e771SFlorian Westphal static inline bool nf_bridge_info_exists(const struct sk_buff *skb)
34c4b0e771SFlorian Westphal {
35de8bda1dSFlorian Westphal 	return skb_ext_exist(skb, SKB_EXT_BRIDGE_NF);
36c4b0e771SFlorian Westphal }
37c4b0e771SFlorian Westphal 
nf_bridge_get_physinif(const struct sk_buff * skb)38c737b7c4SFlorian Westphal static inline int nf_bridge_get_physinif(const struct sk_buff *skb)
39c737b7c4SFlorian Westphal {
40c4b0e771SFlorian Westphal 	const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
41547c4b54SFlorian Westphal 
42c4b0e771SFlorian Westphal 	if (!nf_bridge)
43547c4b54SFlorian Westphal 		return 0;
44547c4b54SFlorian Westphal 
45*98748088SPavel Tikhomirov 	return nf_bridge->physinif;
46c737b7c4SFlorian Westphal }
47c737b7c4SFlorian Westphal 
nf_bridge_get_physoutif(const struct sk_buff * skb)48c737b7c4SFlorian Westphal static inline int nf_bridge_get_physoutif(const struct sk_buff *skb)
49c737b7c4SFlorian Westphal {
50c4b0e771SFlorian Westphal 	const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
51547c4b54SFlorian Westphal 
52c4b0e771SFlorian Westphal 	if (!nf_bridge)
53547c4b54SFlorian Westphal 		return 0;
54547c4b54SFlorian Westphal 
55547c4b54SFlorian Westphal 	return nf_bridge->physoutdev ? nf_bridge->physoutdev->ifindex : 0;
56c737b7c4SFlorian Westphal }
57c737b7c4SFlorian Westphal 
58c737b7c4SFlorian Westphal static inline struct net_device *
nf_bridge_get_physindev(const struct sk_buff * skb,struct net * net)59a54e7219SPavel Tikhomirov nf_bridge_get_physindev(const struct sk_buff *skb, struct net *net)
60c737b7c4SFlorian Westphal {
61c4b0e771SFlorian Westphal 	const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
62c4b0e771SFlorian Westphal 
63*98748088SPavel Tikhomirov 	return nf_bridge ? dev_get_by_index_rcu(net, nf_bridge->physinif) : NULL;
64c737b7c4SFlorian Westphal }
65c737b7c4SFlorian Westphal 
66c737b7c4SFlorian Westphal static inline struct net_device *
nf_bridge_get_physoutdev(const struct sk_buff * skb)67c737b7c4SFlorian Westphal nf_bridge_get_physoutdev(const struct sk_buff *skb)
68c737b7c4SFlorian Westphal {
69c4b0e771SFlorian Westphal 	const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
70c4b0e771SFlorian Westphal 
71c4b0e771SFlorian Westphal 	return nf_bridge ? nf_bridge->physoutdev : NULL;
72c737b7c4SFlorian Westphal }
7372b1e5e4SFlorian Westphal 
nf_bridge_in_prerouting(const struct sk_buff * skb)7472b1e5e4SFlorian Westphal static inline bool nf_bridge_in_prerouting(const struct sk_buff *skb)
7572b1e5e4SFlorian Westphal {
76c4b0e771SFlorian Westphal 	const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
77c4b0e771SFlorian Westphal 
78c4b0e771SFlorian Westphal 	return nf_bridge && nf_bridge->in_prerouting;
7972b1e5e4SFlorian Westphal }
8007317621SStephen Hemminger #else
81a881e963SPeter Huang (Peng) #define br_drop_fake_rtable(skb)	        do { } while (0)
nf_bridge_in_prerouting(const struct sk_buff * skb)8272b1e5e4SFlorian Westphal static inline bool nf_bridge_in_prerouting(const struct sk_buff *skb)
8372b1e5e4SFlorian Westphal {
8472b1e5e4SFlorian Westphal 	return false;
8572b1e5e4SFlorian Westphal }
861da177e4SLinus Torvalds #endif /* CONFIG_BRIDGE_NETFILTER */
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds #endif
89