Commit 797fd391 authored by Julian Anastasov's avatar Julian Anastasov Committed by David S. Miller

netfilter: TCP and raw fix for ip_route_me_harder

TCP in some cases uses different global (raw) socket
to send RST and ACK. The transparent flag is not set there.
Currently, it is a problem for rerouting after the previous
change.

	Fix it by simplifying the checks in ip_route_me_harder
and use FLOWI_FLAG_ANYSRC even for sockets. It looks safe
because the initial routing allowed this source address to
be used and now we just have to make sure the packet is rerouted.

	As a side effect this also allows rerouting for normal
raw sockets that use spoofed source addresses which was not possible
even before we eliminated the ip_route_input call.
Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6602a4ba
...@@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4 = {}; struct flowi4 fl4 = {};
__be32 saddr = iph->saddr; __be32 saddr = iph->saddr;
__u8 flags = 0; __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
unsigned int hh_len; unsigned int hh_len;
if (!skb->sk && addr_type != RTN_LOCAL) { if (addr_type == RTN_UNSPEC)
if (addr_type == RTN_UNSPEC) addr_type = inet_addr_type(net, saddr);
addr_type = inet_addr_type(net, saddr); if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) flags |= FLOWI_FLAG_ANYSRC;
flags |= FLOWI_FLAG_ANYSRC; else
else saddr = 0;
saddr = 0;
}
/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
* packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
...@@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
fl4.flowi4_tos = RT_TOS(iph->tos); fl4.flowi4_tos = RT_TOS(iph->tos);
fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl4.flowi4_mark = skb->mark; fl4.flowi4_mark = skb->mark;
fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; fl4.flowi4_flags = flags;
rt = ip_route_output_key(net, &fl4); rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return -1; return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment