about coding details of tproxy
hello, all: I have been reseach on tproxy(for kernel-2.6.24) these days. And I found that Tproxy sets skb->mark and skb->sk first (both the TPROXY target and socket match do the same), then hand packets to non-local sockets rely on policy routing. Today I saw that Tproxy has modified ip_route_me_harder, it inserted lines of code to ip_route_me_harder like following: so, what does ip_route_me_harder used for, why Tproxy modified those codes. thanks very much! /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) { const struct iphdr *iph = ip_hdr(skb); struct rtable *rt; struct flowi fl = {}; struct dst_entry *odst; unsigned int hh_len; unsigned int type; type = inet_addr_type(iph->saddr); if (skb->sk && inet_sk(skb->sk)->transparent) //TPROXY ADDED type = RTN_LOCAL; if (addr_type == RTN_UNSPEC) addr_type = type; /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook. */ if (addr_type == RTN_LOCAL) { fl.nl_u.ip4_u.daddr = iph->daddr; if (type == RTN_LOCAL) fl.nl_u.ip4_u.saddr = iph->saddr; fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl.mark = skb->mark; fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; //TPROXY ADDED if (ip_route_output_key(&rt, &fl) != 0) return -1; /* Drop old route. */ dst_release(skb->dst); skb->dst = &rt->u.dst; } else { /* non-local src, find valid iif to satisfy * rp-filter when calling ip_route_input. */ fl.nl_u.ip4_u.daddr = iph->saddr; if (ip_route_output_key(&rt, &fl) != 0) return -1; odst = skb->dst; if (ip_route_input(skb, iph->daddr, iph->saddr, RT_TOS(iph->tos), rt->u.dst.dev) != 0) { dst_release(&rt->u.dst); return -1; } dst_release(&rt->u.dst); dst_release(odst); } if (skb->dst->error) return -1; #ifdef CONFIG_XFRM if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && xfrm_decode_session(skb, &fl, AF_INET) == 0) if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0)) return -1; #endif /* Change in oif may mean change in hh_len. */ hh_len = skb->dst->dev->hard_header_len; if (skb_headroom(skb) < hh_len && pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) return -1; return 0; } regards.
participants (1)
-
kudiejlq