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 #ifdef CONFIG_NETFILTER_EGRESS 51 RCU_INIT_POINTER(dev->nf_hooks_egress, NULL); 52 #endif 53 } 54 55 #ifdef CONFIG_NETFILTER_INGRESS 56 static inline bool nf_hook_ingress_active(const struct sk_buff *skb) 57 { 58 return nf_hook_netdev_active(NF_NETDEV_INGRESS, 59 skb->dev->nf_hooks_ingress); 60 } 61 62 static inline int nf_hook_ingress(struct sk_buff *skb) 63 { 64 return nf_hook_netdev(skb, NF_NETDEV_INGRESS, 65 skb->dev->nf_hooks_ingress); 66 } 67 #else /* CONFIG_NETFILTER_INGRESS */ 68 static inline int nf_hook_ingress_active(struct sk_buff *skb) 69 { 70 return 0; 71 } 72 73 static inline int nf_hook_ingress(struct sk_buff *skb) 74 { 75 return 0; 76 } 77 #endif /* CONFIG_NETFILTER_INGRESS */ 78 79 #ifdef CONFIG_NETFILTER_EGRESS 80 static inline bool nf_hook_egress_active(const struct sk_buff *skb) 81 { 82 return nf_hook_netdev_active(NF_NETDEV_EGRESS, 83 skb->dev->nf_hooks_egress); 84 } 85 86 static inline int nf_hook_egress(struct sk_buff *skb) 87 { 88 return nf_hook_netdev(skb, NF_NETDEV_EGRESS, 89 skb->dev->nf_hooks_egress); 90 } 91 #else /* CONFIG_NETFILTER_EGRESS */ 92 static inline int nf_hook_egress_active(struct sk_buff *skb) 93 { 94 return 0; 95 } 96 97 static inline int nf_hook_egress(struct sk_buff *skb) 98 { 99 return 0; 100 } 101 #endif /* CONFIG_NETFILTER_EGRESS */ 102 #endif /* _NETFILTER_INGRESS_H_ */ 103