xref: /linux-6.15/include/linux/netfilter_ipv6.h (revision 514fcaac)
1 /* IPv6-specific defines for netfilter.
2  * (C)1998 Rusty Russell -- This code is GPL.
3  * (C)1999 David Jeffery
4  *   this header was blatantly ripped from netfilter_ipv4.h
5  *   it's amazing what adding a bunch of 6s can do =8^)
6  */
7 #ifndef __LINUX_IP6_NETFILTER_H
8 #define __LINUX_IP6_NETFILTER_H
9 
10 #include <uapi/linux/netfilter_ipv6.h>
11 
12 /* Extra routing may needed on local out, as the QUEUE target never returns
13  * control to the table.
14  */
15 struct ip6_rt_info {
16 	struct in6_addr daddr;
17 	struct in6_addr saddr;
18 	u_int32_t mark;
19 };
20 
21 struct nf_queue_entry;
22 struct nf_ct_bridge_frag_data;
23 
24 /*
25  * Hook functions for ipv6 to allow xt_* modules to be built-in even
26  * if IPv6 is a module.
27  */
28 struct nf_ipv6_ops {
29 #if IS_MODULE(CONFIG_IPV6)
30 	int (*chk_addr)(struct net *net, const struct in6_addr *addr,
31 			const struct net_device *dev, int strict);
32 	int (*route_me_harder)(struct net *net, struct sk_buff *skb);
33 	int (*dev_get_saddr)(struct net *net, const struct net_device *dev,
34 		       const struct in6_addr *daddr, unsigned int srcprefs,
35 		       struct in6_addr *saddr);
36 	int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl,
37 		     bool strict);
38 #endif
39 	void (*route_input)(struct sk_buff *skb);
40 	int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb,
41 			int (*output)(struct net *, struct sock *, struct sk_buff *));
42 	int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry);
43 #if IS_MODULE(CONFIG_IPV6)
44 	int (*br_defrag)(struct net *net, struct sk_buff *skb, u32 user);
45 	int (*br_fragment)(struct net *net, struct sock *sk,
46 			   struct sk_buff *skb,
47 			   struct nf_ct_bridge_frag_data *data,
48 			   int (*output)(struct net *, struct sock *sk,
49 					 const struct nf_ct_bridge_frag_data *data,
50 					 struct sk_buff *));
51 #endif
52 };
53 
54 #ifdef CONFIG_NETFILTER
55 #include <net/addrconf.h>
56 
57 extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops;
58 static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void)
59 {
60 	return rcu_dereference(nf_ipv6_ops);
61 }
62 
63 static inline int nf_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
64 				   const struct net_device *dev, int strict)
65 {
66 #if IS_MODULE(CONFIG_IPV6)
67 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
68 
69 	if (!v6_ops)
70 		return 1;
71 
72 	return v6_ops->chk_addr(net, addr, dev, strict);
73 #else
74 	return ipv6_chk_addr(net, addr, dev, strict);
75 #endif
76 }
77 
78 int __nf_ip6_route(struct net *net, struct dst_entry **dst,
79 			       struct flowi *fl, bool strict);
80 
81 static inline int nf_ip6_route(struct net *net, struct dst_entry **dst,
82 			       struct flowi *fl, bool strict)
83 {
84 #if IS_MODULE(CONFIG_IPV6)
85 	const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
86 
87 	if (v6ops)
88 		return v6ops->route(net, dst, fl, strict);
89 
90 	return -EHOSTUNREACH;
91 #endif
92 #if IS_BUILTIN(CONFIG_IPV6)
93 	return __nf_ip6_route(net, dst, fl, strict);
94 #else
95 	return -EHOSTUNREACH;
96 #endif
97 }
98 
99 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
100 
101 static inline int nf_ipv6_br_defrag(struct net *net, struct sk_buff *skb,
102 				    u32 user)
103 {
104 #if IS_MODULE(CONFIG_IPV6)
105 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
106 
107 	if (!v6_ops)
108 		return 1;
109 
110 	return v6_ops->br_defrag(net, skb, user);
111 #else
112 	return nf_ct_frag6_gather(net, skb, user);
113 #endif
114 }
115 
116 int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
117 		    struct nf_ct_bridge_frag_data *data,
118 		    int (*output)(struct net *, struct sock *sk,
119 				  const struct nf_ct_bridge_frag_data *data,
120 				  struct sk_buff *));
121 
122 static inline int nf_br_ip6_fragment(struct net *net, struct sock *sk,
123 				     struct sk_buff *skb,
124 				     struct nf_ct_bridge_frag_data *data,
125 				     int (*output)(struct net *, struct sock *sk,
126 						   const struct nf_ct_bridge_frag_data *data,
127 						   struct sk_buff *))
128 {
129 #if IS_MODULE(CONFIG_IPV6)
130 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
131 
132 	if (!v6_ops)
133 		return 1;
134 
135 	return v6_ops->br_fragment(net, sk, skb, data, output);
136 #else
137 	return br_ip6_fragment(net, sk, skb, data, output);
138 #endif
139 }
140 
141 int ip6_route_me_harder(struct net *net, struct sk_buff *skb);
142 
143 static inline int nf_ip6_route_me_harder(struct net *net, struct sk_buff *skb)
144 {
145 #if IS_MODULE(CONFIG_IPV6)
146 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
147 
148 	if (!v6_ops)
149 		return -EHOSTUNREACH;
150 
151 	return v6_ops->route_me_harder(net, skb);
152 #else
153 	return ip6_route_me_harder(net, skb);
154 #endif
155 }
156 
157 __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
158 			unsigned int dataoff, u_int8_t protocol);
159 
160 int ipv6_netfilter_init(void);
161 void ipv6_netfilter_fini(void);
162 
163 #else /* CONFIG_NETFILTER */
164 static inline int ipv6_netfilter_init(void) { return 0; }
165 static inline void ipv6_netfilter_fini(void) { return; }
166 static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void) { return NULL; }
167 #endif /* CONFIG_NETFILTER */
168 
169 #endif /*__LINUX_IP6_NETFILTER_H*/
170