1 #ifndef _NF_TPROXY_H_
2 #define _NF_TPROXY_H_
3 
4 #include <net/tcp.h>
5 
6 enum nf_tproxy_lookup_t {
7 	 NF_TPROXY_LOOKUP_LISTENER,
8 	 NF_TPROXY_LOOKUP_ESTABLISHED,
9 };
10 
nf_tproxy_sk_is_transparent(struct sock * sk)11 static inline bool nf_tproxy_sk_is_transparent(struct sock *sk)
12 {
13 	if (inet_sk_transparent(sk))
14 		return true;
15 
16 	sock_gen_put(sk);
17 	return false;
18 }
19 
nf_tproxy_twsk_deschedule_put(struct inet_timewait_sock * tw)20 static inline void nf_tproxy_twsk_deschedule_put(struct inet_timewait_sock *tw)
21 {
22 	local_bh_disable();
23 	inet_twsk_deschedule_put(tw);
24 	local_bh_enable();
25 }
26 
27 /* assign a socket to the skb -- consumes sk */
nf_tproxy_assign_sock(struct sk_buff * skb,struct sock * sk)28 static inline void nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
29 {
30 	skb_orphan(skb);
31 	skb->sk = sk;
32 	skb->destructor = sock_edemux;
33 }
34 
35 __be32 nf_tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr);
36 
37 /**
38  * nf_tproxy_handle_time_wait4 - handle IPv4 TCP TIME_WAIT reopen redirections
39  * @skb:	The skb being processed.
40  * @laddr:	IPv4 address to redirect to or zero.
41  * @lport:	TCP port to redirect to or zero.
42  * @sk:		The TIME_WAIT TCP socket found by the lookup.
43  *
44  * We have to handle SYN packets arriving to TIME_WAIT sockets
45  * differently: instead of reopening the connection we should rather
46  * redirect the new connection to the proxy if there's a listener
47  * socket present.
48  *
49  * nf_tproxy_handle_time_wait4() consumes the socket reference passed in.
50  *
51  * Returns the listener socket if there's one, the TIME_WAIT socket if
52  * no such listener is found, or NULL if the TCP header is incomplete.
53  */
54 struct sock *
55 nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb,
56 			    __be32 laddr, __be16 lport, struct sock *sk);
57 
58 /*
59  * This is used when the user wants to intercept a connection matching
60  * an explicit iptables rule. In this case the sockets are assumed
61  * matching in preference order:
62  *
63  *   - match: if there's a fully established connection matching the
64  *     _packet_ tuple, it is returned, assuming the redirection
65  *     already took place and we process a packet belonging to an
66  *     established connection
67  *
68  *   - match: if there's a listening socket matching the redirection
69  *     (e.g. on-port & on-ip of the connection), it is returned,
70  *     regardless if it was bound to 0.0.0.0 or an explicit
71  *     address. The reasoning is that if there's an explicit rule, it
72  *     does not really matter if the listener is bound to an interface
73  *     or to 0. The user already stated that he wants redirection
74  *     (since he added the rule).
75  *
76  * Please note that there's an overlap between what a TPROXY target
77  * and a socket match will match. Normally if you have both rules the
78  * "socket" match will be the first one, effectively all packets
79  * belonging to established connections going through that one.
80  */
81 struct sock *
82 nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb,
83 		      const u8 protocol,
84 		      const __be32 saddr, const __be32 daddr,
85 		      const __be16 sport, const __be16 dport,
86 		      const struct net_device *in,
87 		      const enum nf_tproxy_lookup_t lookup_type);
88 
89 const struct in6_addr *
90 nf_tproxy_laddr6(struct sk_buff *skb, const struct in6_addr *user_laddr,
91 		 const struct in6_addr *daddr);
92 
93 /**
94  * nf_tproxy_handle_time_wait6 - handle IPv6 TCP TIME_WAIT reopen redirections
95  * @skb:	The skb being processed.
96  * @tproto:	Transport protocol.
97  * @thoff:	Transport protocol header offset.
98  * @net:	Network namespace.
99  * @laddr:	IPv6 address to redirect to.
100  * @lport:	TCP port to redirect to or zero.
101  * @sk:		The TIME_WAIT TCP socket found by the lookup.
102  *
103  * We have to handle SYN packets arriving to TIME_WAIT sockets
104  * differently: instead of reopening the connection we should rather
105  * redirect the new connection to the proxy if there's a listener
106  * socket present.
107  *
108  * nf_tproxy_handle_time_wait6() consumes the socket reference passed in.
109  *
110  * Returns the listener socket if there's one, the TIME_WAIT socket if
111  * no such listener is found, or NULL if the TCP header is incomplete.
112  */
113 struct sock *
114 nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
115 			    struct net *net,
116 			    const struct in6_addr *laddr,
117 			    const __be16 lport,
118 			    struct sock *sk);
119 
120 struct sock *
121 nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff,
122 		      const u8 protocol,
123 		      const struct in6_addr *saddr, const struct in6_addr *daddr,
124 		      const __be16 sport, const __be16 dport,
125 		      const struct net_device *in,
126 		      const enum nf_tproxy_lookup_t lookup_type);
127 
128 #endif /* _NF_TPROXY_H_ */
129