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