1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _NETFILTER_NETDEV_H_ 3 #define _NETFILTER_NETDEV_H_ 4 5 #include <linux/netfilter.h> 6 #include <linux/netdevice.h> 7 8 #ifdef CONFIG_NETFILTER 9 static __always_inline bool nf_hook_netdev_active(enum nf_dev_hooks hooknum, 10 struct nf_hook_entries __rcu *hooks) 11 { 12 #ifdef CONFIG_JUMP_LABEL 13 if (!static_key_false(&nf_hooks_needed[NFPROTO_NETDEV][hooknum])) 14 return false; 15 #endif 16 return rcu_access_pointer(hooks); 17 } 18 19 /* caller must hold rcu_read_lock */ 20 static __always_inline int nf_hook_netdev(struct sk_buff *skb, 21 enum nf_dev_hooks hooknum, 22 struct nf_hook_entries __rcu *hooks) 23 { 24 struct nf_hook_entries *e = rcu_dereference(hooks); 25 struct nf_hook_state state; 26 int ret; 27 28 /* Must recheck the hook head, in the event it became NULL 29 * after the check in nf_hook_netdev_active evaluated to true. 30 */ 31 if (unlikely(!e)) 32 return 0; 33 34 nf_hook_state_init(&state, hooknum, 35 NFPROTO_NETDEV, skb->dev, NULL, NULL, 36 dev_net(skb->dev), NULL); 37 ret = nf_hook_slow(skb, &state, e, 0); 38 if (ret == 0) 39 return -1; 40 41 return ret; 42 } 43 #endif /* CONFIG_NETFILTER */ 44 45 static inline void nf_hook_netdev_init(struct net_device *dev) 46 { 47 #ifdef CONFIG_NETFILTER_INGRESS 48 RCU_INIT_POINTER(dev->nf_hooks_ingress, NULL); 49 #endif 50 } 51 52 #ifdef CONFIG_NETFILTER_INGRESS 53 static inline bool nf_hook_ingress_active(const struct sk_buff *skb) 54 { 55 return nf_hook_netdev_active(NF_NETDEV_INGRESS, 56 skb->dev->nf_hooks_ingress); 57 } 58 59 static inline int nf_hook_ingress(struct sk_buff *skb) 60 { 61 return nf_hook_netdev(skb, NF_NETDEV_INGRESS, 62 skb->dev->nf_hooks_ingress); 63 } 64 #else /* CONFIG_NETFILTER_INGRESS */ 65 static inline int nf_hook_ingress_active(struct sk_buff *skb) 66 { 67 return 0; 68 } 69 70 static inline int nf_hook_ingress(struct sk_buff *skb) 71 { 72 return 0; 73 } 74 #endif /* CONFIG_NETFILTER_INGRESS */ 75 #endif /* _NETFILTER_INGRESS_H_ */ 76