12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/module.h>
20 #include <linux/netfilter/x_tables.h>
21 #include <linux/netfilter_ipv4/ip_tables.h>
25 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
26 #define XT_TPROXY_HAVE_IPV6 1
29 #include <linux/netfilter_ipv6/ip6_tables.h>
36 static bool tproxy_sk_is_transparent(
struct sock *
sk)
39 if (inet_sk(sk)->transparent)
43 if (inet_twsk(sk)->tw_transparent)
53 struct in_device *indev;
61 indev = __in_dev_get_rcu(skb->
dev);
62 for_primary_ifa(indev) {
63 laddr = ifa->ifa_local;
68 return laddr ? laddr :
daddr;
92 const struct iphdr *iph = ip_hdr(skb);
95 hp = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(_hdr), &_hdr);
101 if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
106 sk2 = nf_tproxy_get_sock_v4(dev_net(skb->
dev), iph->
protocol,
124 const struct iphdr *iph = ip_hdr(skb);
128 hp = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(_hdr), &_hdr);
136 sk = nf_tproxy_get_sock_v4(dev_net(skb->
dev), iph->
protocol,
141 laddr = tproxy_laddr4(skb, laddr, iph->
daddr);
148 sk = tproxy_handle_time_wait4(skb, laddr, lport, sk);
152 sk = nf_tproxy_get_sock_v4(dev_net(skb->
dev), iph->
protocol,
158 if (sk && tproxy_sk_is_transparent(sk)) {
161 skb->
mark = (skb->
mark & ~mark_mask) ^ mark_value;
163 pr_debug(
"redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
171 pr_debug(
"no socket, dropping: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
193 #ifdef XT_TPROXY_HAVE_IPV6
195 static inline const struct in6_addr *
203 if (!ipv6_addr_any(user_laddr))
208 indev = __in6_dev_get(skb->
dev);
219 return laddr ? laddr :
daddr;
241 tproxy_handle_time_wait6(
struct sk_buff *skb,
int tproto,
int thoff,
245 const struct ipv6hdr *iph = ipv6_hdr(skb);
249 hp = skb_header_pointer(skb, thoff,
sizeof(_hdr), &_hdr);
255 if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
260 sk2 = nf_tproxy_get_sock_v6(dev_net(skb->
dev), tproto,
279 const struct ipv6hdr *iph = ipv6_hdr(skb);
290 pr_debug(
"unable to find transport header in IPv6 packet, dropping\n");
294 hp = skb_header_pointer(skb, thoff,
sizeof(_hdr), &_hdr);
296 pr_debug(
"unable to grab transport header contents in IPv6 packet, dropping\n");
304 sk = nf_tproxy_get_sock_v6(dev_net(skb->
dev), tproto,
315 sk = tproxy_handle_time_wait6(skb, tproto, thoff, par, sk);
319 sk = nf_tproxy_get_sock_v6(dev_net(skb->
dev), tproto,
325 if (sk && tproxy_sk_is_transparent(sk)) {
330 pr_debug(
"redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n",
338 pr_debug(
"no socket, dropping: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n",
353 pr_info(
"Can be used only in combination with "
354 "either -p tcp or -p udp\n");
367 pr_info(
"Can be used only in combination with "
368 "either -p tcp or -p udp\n");
377 .target = tproxy_tg4_v0,
380 .checkentry = tproxy_tg4_check,
388 .target = tproxy_tg4_v1,
391 .checkentry = tproxy_tg4_check,
395 #ifdef XT_TPROXY_HAVE_IPV6
400 .target = tproxy_tg6_v1,
403 .checkentry = tproxy_tg6_check,
411 static int __init tproxy_tg_init(
void)
414 #ifdef XT_TPROXY_HAVE_IPV6
421 static void __exit tproxy_tg_exit(
void)