xref: /linux-6.15/include/linux/netfilter_ipv6.h (revision 7577bc82)
11da177e4SLinus Torvalds /* IPv6-specific defines for netfilter.
21da177e4SLinus Torvalds  * (C)1998 Rusty Russell -- This code is GPL.
31da177e4SLinus Torvalds  * (C)1999 David Jeffery
41da177e4SLinus Torvalds  *   this header was blatantly ripped from netfilter_ipv4.h
51da177e4SLinus Torvalds  *   it's amazing what adding a bunch of 6s can do =8^)
61da177e4SLinus Torvalds  */
7607ca46eSDavid Howells #ifndef __LINUX_IP6_NETFILTER_H
8607ca46eSDavid Howells #define __LINUX_IP6_NETFILTER_H
91da177e4SLinus Torvalds 
10607ca46eSDavid Howells #include <uapi/linux/netfilter_ipv6.h>
113006a522SFernando Fernandez Mancera #include <net/tcp.h>
121da177e4SLinus Torvalds 
1344dde236SJeremy Sowden /* Check for an extension */
1444dde236SJeremy Sowden static inline int
nf_ip6_ext_hdr(u8 nexthdr)1544dde236SJeremy Sowden nf_ip6_ext_hdr(u8 nexthdr)
1644dde236SJeremy Sowden {	return (nexthdr == IPPROTO_HOPOPTS) ||
1744dde236SJeremy Sowden 	       (nexthdr == IPPROTO_ROUTING) ||
1844dde236SJeremy Sowden 	       (nexthdr == IPPROTO_FRAGMENT) ||
1944dde236SJeremy Sowden 	       (nexthdr == IPPROTO_ESP) ||
2044dde236SJeremy Sowden 	       (nexthdr == IPPROTO_AH) ||
2144dde236SJeremy Sowden 	       (nexthdr == IPPROTO_NONE) ||
2244dde236SJeremy Sowden 	       (nexthdr == IPPROTO_DSTOPTS);
2344dde236SJeremy Sowden }
2444dde236SJeremy Sowden 
257db9a51eSPablo Neira Ayuso /* Extra routing may needed on local out, as the QUEUE target never returns
267db9a51eSPablo Neira Ayuso  * control to the table.
277db9a51eSPablo Neira Ayuso  */
287db9a51eSPablo Neira Ayuso struct ip6_rt_info {
297db9a51eSPablo Neira Ayuso 	struct in6_addr daddr;
307db9a51eSPablo Neira Ayuso 	struct in6_addr saddr;
317db9a51eSPablo Neira Ayuso 	u_int32_t mark;
327db9a51eSPablo Neira Ayuso };
337db9a51eSPablo Neira Ayuso 
34ce388f45SPablo Neira Ayuso struct nf_queue_entry;
3546705b07SJeremy Sowden struct nf_bridge_frag_data;
36ce388f45SPablo Neira Ayuso 
372a7851bfSFlorian Westphal /*
382a7851bfSFlorian Westphal  * Hook functions for ipv6 to allow xt_* modules to be built-in even
392a7851bfSFlorian Westphal  * if IPv6 is a module.
402a7851bfSFlorian Westphal  */
412a7851bfSFlorian Westphal struct nf_ipv6_ops {
42ac02bcf9SFlorian Westphal #if IS_MODULE(CONFIG_IPV6)
432a7851bfSFlorian Westphal 	int (*chk_addr)(struct net *net, const struct in6_addr *addr,
442a7851bfSFlorian Westphal 			const struct net_device *dev, int strict);
4546d6c5aeSJason A. Donenfeld 	int (*route_me_harder)(struct net *net, struct sock *sk, struct sk_buff *skb);
4696058728SFlorian Westphal 	int (*dev_get_saddr)(struct net *net, const struct net_device *dev,
4796058728SFlorian Westphal 		       const struct in6_addr *daddr, unsigned int srcprefs,
4896058728SFlorian Westphal 		       struct in6_addr *saddr);
49ac02bcf9SFlorian Westphal 	int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl,
50ac02bcf9SFlorian Westphal 		     bool strict);
513006a522SFernando Fernandez Mancera 	u32 (*cookie_init_sequence)(const struct ipv6hdr *iph,
523006a522SFernando Fernandez Mancera 				    const struct tcphdr *th, u16 *mssp);
533006a522SFernando Fernandez Mancera 	int (*cookie_v6_check)(const struct ipv6hdr *iph,
54*7577bc82SKuniyuki Iwashima 			       const struct tcphdr *th);
5596058728SFlorian Westphal #endif
56ac02bcf9SFlorian Westphal 	void (*route_input)(struct sk_buff *skb);
57ac02bcf9SFlorian Westphal 	int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb,
58ac02bcf9SFlorian Westphal 			int (*output)(struct net *, struct sock *, struct sk_buff *));
59ac02bcf9SFlorian Westphal 	int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry);
60764dd163SPablo Neira Ayuso #if IS_MODULE(CONFIG_IPV6)
61764dd163SPablo Neira Ayuso 	int (*br_fragment)(struct net *net, struct sock *sk,
62764dd163SPablo Neira Ayuso 			   struct sk_buff *skb,
6346705b07SJeremy Sowden 			   struct nf_bridge_frag_data *data,
64764dd163SPablo Neira Ayuso 			   int (*output)(struct net *, struct sock *sk,
6546705b07SJeremy Sowden 					 const struct nf_bridge_frag_data *data,
66764dd163SPablo Neira Ayuso 					 struct sk_buff *));
67764dd163SPablo Neira Ayuso #endif
682a7851bfSFlorian Westphal };
692a7851bfSFlorian Westphal 
702e4cfae2SJoe Stringer #ifdef CONFIG_NETFILTER
71ac02bcf9SFlorian Westphal #include <net/addrconf.h>
722e4cfae2SJoe Stringer 
732a7851bfSFlorian Westphal extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops;
nf_get_ipv6_ops(void)742a7851bfSFlorian Westphal static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void)
752a7851bfSFlorian Westphal {
762a7851bfSFlorian Westphal 	return rcu_dereference(nf_ipv6_ops);
772a7851bfSFlorian Westphal }
782a7851bfSFlorian Westphal 
nf_ipv6_chk_addr(struct net * net,const struct in6_addr * addr,const struct net_device * dev,int strict)79ac02bcf9SFlorian Westphal static inline int nf_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
80ac02bcf9SFlorian Westphal 				   const struct net_device *dev, int strict)
81ac02bcf9SFlorian Westphal {
82ac02bcf9SFlorian Westphal #if IS_MODULE(CONFIG_IPV6)
83ac02bcf9SFlorian Westphal 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
84ac02bcf9SFlorian Westphal 
85ac02bcf9SFlorian Westphal 	if (!v6_ops)
86ac02bcf9SFlorian Westphal 		return 1;
87ac02bcf9SFlorian Westphal 
88ac02bcf9SFlorian Westphal 	return v6_ops->chk_addr(net, addr, dev, strict);
8943a38c3fSArnd Bergmann #elif IS_BUILTIN(CONFIG_IPV6)
90ac02bcf9SFlorian Westphal 	return ipv6_chk_addr(net, addr, dev, strict);
9143a38c3fSArnd Bergmann #else
9243a38c3fSArnd Bergmann 	return 1;
93ac02bcf9SFlorian Westphal #endif
94ac02bcf9SFlorian Westphal }
95ac02bcf9SFlorian Westphal 
96ac02bcf9SFlorian Westphal int __nf_ip6_route(struct net *net, struct dst_entry **dst,
97ac02bcf9SFlorian Westphal 			       struct flowi *fl, bool strict);
98ac02bcf9SFlorian Westphal 
nf_ip6_route(struct net * net,struct dst_entry ** dst,struct flowi * fl,bool strict)99ac02bcf9SFlorian Westphal static inline int nf_ip6_route(struct net *net, struct dst_entry **dst,
100ac02bcf9SFlorian Westphal 			       struct flowi *fl, bool strict)
101ac02bcf9SFlorian Westphal {
102ac02bcf9SFlorian Westphal #if IS_MODULE(CONFIG_IPV6)
103ac02bcf9SFlorian Westphal 	const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
104ac02bcf9SFlorian Westphal 
105ac02bcf9SFlorian Westphal 	if (v6ops)
106ac02bcf9SFlorian Westphal 		return v6ops->route(net, dst, fl, strict);
107ac02bcf9SFlorian Westphal 
108ac02bcf9SFlorian Westphal 	return -EHOSTUNREACH;
109ac02bcf9SFlorian Westphal #endif
110ac02bcf9SFlorian Westphal #if IS_BUILTIN(CONFIG_IPV6)
111ac02bcf9SFlorian Westphal 	return __nf_ip6_route(net, dst, fl, strict);
112ac02bcf9SFlorian Westphal #else
113ac02bcf9SFlorian Westphal 	return -EHOSTUNREACH;
114ac02bcf9SFlorian Westphal #endif
115ac02bcf9SFlorian Westphal }
116ac02bcf9SFlorian Westphal 
117c9bb6165SPablo Neira Ayuso #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
118c9bb6165SPablo Neira Ayuso 
119764dd163SPablo Neira Ayuso int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
12046705b07SJeremy Sowden 		    struct nf_bridge_frag_data *data,
121764dd163SPablo Neira Ayuso 		    int (*output)(struct net *, struct sock *sk,
12246705b07SJeremy Sowden 				  const struct nf_bridge_frag_data *data,
123764dd163SPablo Neira Ayuso 				  struct sk_buff *));
124764dd163SPablo Neira Ayuso 
nf_br_ip6_fragment(struct net * net,struct sock * sk,struct sk_buff * skb,struct nf_bridge_frag_data * data,int (* output)(struct net *,struct sock * sk,const struct nf_bridge_frag_data * data,struct sk_buff *))125764dd163SPablo Neira Ayuso static inline int nf_br_ip6_fragment(struct net *net, struct sock *sk,
126764dd163SPablo Neira Ayuso 				     struct sk_buff *skb,
12746705b07SJeremy Sowden 				     struct nf_bridge_frag_data *data,
128764dd163SPablo Neira Ayuso 				     int (*output)(struct net *, struct sock *sk,
12946705b07SJeremy Sowden 						   const struct nf_bridge_frag_data *data,
130764dd163SPablo Neira Ayuso 						   struct sk_buff *))
131764dd163SPablo Neira Ayuso {
132764dd163SPablo Neira Ayuso #if IS_MODULE(CONFIG_IPV6)
133764dd163SPablo Neira Ayuso 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
134764dd163SPablo Neira Ayuso 
135764dd163SPablo Neira Ayuso 	if (!v6_ops)
136764dd163SPablo Neira Ayuso 		return 1;
137764dd163SPablo Neira Ayuso 
138764dd163SPablo Neira Ayuso 	return v6_ops->br_fragment(net, sk, skb, data, output);
13943a38c3fSArnd Bergmann #elif IS_BUILTIN(CONFIG_IPV6)
140764dd163SPablo Neira Ayuso 	return br_ip6_fragment(net, sk, skb, data, output);
14143a38c3fSArnd Bergmann #else
14243a38c3fSArnd Bergmann 	return 1;
143764dd163SPablo Neira Ayuso #endif
144764dd163SPablo Neira Ayuso }
145764dd163SPablo Neira Ayuso 
14646d6c5aeSJason A. Donenfeld int ip6_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb);
147c1deb065SFlorian Westphal 
nf_ip6_route_me_harder(struct net * net,struct sock * sk,struct sk_buff * skb)14846d6c5aeSJason A. Donenfeld static inline int nf_ip6_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb)
149c1deb065SFlorian Westphal {
150c1deb065SFlorian Westphal #if IS_MODULE(CONFIG_IPV6)
151c1deb065SFlorian Westphal 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
152c1deb065SFlorian Westphal 
153c1deb065SFlorian Westphal 	if (!v6_ops)
154c1deb065SFlorian Westphal 		return -EHOSTUNREACH;
155c1deb065SFlorian Westphal 
15646d6c5aeSJason A. Donenfeld 	return v6_ops->route_me_harder(net, sk, skb);
15743a38c3fSArnd Bergmann #elif IS_BUILTIN(CONFIG_IPV6)
15846d6c5aeSJason A. Donenfeld 	return ip6_route_me_harder(net, sk, skb);
15943a38c3fSArnd Bergmann #else
16043a38c3fSArnd Bergmann 	return -EHOSTUNREACH;
161c1deb065SFlorian Westphal #endif
162c1deb065SFlorian Westphal }
163c1deb065SFlorian Westphal 
nf_ipv6_cookie_init_sequence(const struct ipv6hdr * iph,const struct tcphdr * th,u16 * mssp)1643006a522SFernando Fernandez Mancera static inline u32 nf_ipv6_cookie_init_sequence(const struct ipv6hdr *iph,
1653006a522SFernando Fernandez Mancera 					       const struct tcphdr *th,
1663006a522SFernando Fernandez Mancera 					       u16 *mssp)
1673006a522SFernando Fernandez Mancera {
1688527fa6cSArnd Bergmann #if IS_ENABLED(CONFIG_SYN_COOKIES)
1693006a522SFernando Fernandez Mancera #if IS_MODULE(CONFIG_IPV6)
1703006a522SFernando Fernandez Mancera 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
1713006a522SFernando Fernandez Mancera 
1723006a522SFernando Fernandez Mancera 	if (v6_ops)
1733006a522SFernando Fernandez Mancera 		return v6_ops->cookie_init_sequence(iph, th, mssp);
1748527fa6cSArnd Bergmann #elif IS_BUILTIN(CONFIG_IPV6)
1753006a522SFernando Fernandez Mancera 	return __cookie_v6_init_sequence(iph, th, mssp);
1763006a522SFernando Fernandez Mancera #endif
1778527fa6cSArnd Bergmann #endif
1788527fa6cSArnd Bergmann 	return 0;
1793006a522SFernando Fernandez Mancera }
1803006a522SFernando Fernandez Mancera 
nf_cookie_v6_check(const struct ipv6hdr * iph,const struct tcphdr * th)1813006a522SFernando Fernandez Mancera static inline int nf_cookie_v6_check(const struct ipv6hdr *iph,
182*7577bc82SKuniyuki Iwashima 				     const struct tcphdr *th)
1833006a522SFernando Fernandez Mancera {
1848527fa6cSArnd Bergmann #if IS_ENABLED(CONFIG_SYN_COOKIES)
1853006a522SFernando Fernandez Mancera #if IS_MODULE(CONFIG_IPV6)
1863006a522SFernando Fernandez Mancera 	const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
1873006a522SFernando Fernandez Mancera 
1883006a522SFernando Fernandez Mancera 	if (v6_ops)
189*7577bc82SKuniyuki Iwashima 		return v6_ops->cookie_v6_check(iph, th);
1908527fa6cSArnd Bergmann #elif IS_BUILTIN(CONFIG_IPV6)
191*7577bc82SKuniyuki Iwashima 	return __cookie_v6_check(iph, th);
1923006a522SFernando Fernandez Mancera #endif
1938527fa6cSArnd Bergmann #endif
1948527fa6cSArnd Bergmann 	return 0;
1953006a522SFernando Fernandez Mancera }
1963006a522SFernando Fernandez Mancera 
197ac02bcf9SFlorian Westphal __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
198ac02bcf9SFlorian Westphal 			unsigned int dataoff, u_int8_t protocol);
199ac02bcf9SFlorian Westphal 
20028e144cfSXin Long int nf_ip6_check_hbh_len(struct sk_buff *skb, u32 *plen);
20128e144cfSXin Long 
202ac02bcf9SFlorian Westphal int ipv6_netfilter_init(void);
203ac02bcf9SFlorian Westphal void ipv6_netfilter_fini(void);
204ac02bcf9SFlorian Westphal 
205bb94aa16SPatrick McHardy #else /* CONFIG_NETFILTER */
ipv6_netfilter_init(void)206bb94aa16SPatrick McHardy static inline int ipv6_netfilter_init(void) { return 0; }
ipv6_netfilter_fini(void)207bb94aa16SPatrick McHardy static inline void ipv6_netfilter_fini(void) { return; }
nf_get_ipv6_ops(void)2082e4cfae2SJoe Stringer static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void) { return NULL; }
209bb94aa16SPatrick McHardy #endif /* CONFIG_NETFILTER */
2102cc7d573SHarald Welte 
2111da177e4SLinus Torvalds #endif /*__LINUX_IP6_NETFILTER_H*/
212