diff options
author | Patrick McHardy <kaber@trash.net> | 2013-04-05 06:41:10 +0000 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-04-08 12:34:00 +0200 |
commit | c9e1673a0accf086dfce9b501d8bcb4ec6bbc1e9 (patch) | |
tree | 7a7b6de83f82c9bbad878c3ead23dd2ad4b59c32 /net/ipv4/netfilter.c | |
parent | 6b0ee8c036ecb3ac92e18e6ca0dca7bff88beaf0 (diff) | |
download | blackbird-op-linux-c9e1673a0accf086dfce9b501d8bcb4ec6bbc1e9.tar.gz blackbird-op-linux-c9e1673a0accf086dfce9b501d8bcb4ec6bbc1e9.zip |
netfilter: ipv4: propagate routing errors from ip_route_me_harder()
Propagate routing errors from ip_route_me_harder() when dropping a packet
using NF_DROP_ERR(). This makes userspace get the proper error instead of
EPERM for everything.
Example:
# ip r a unreachable default table 100
# ip ru add fwmark 0x1 lookup 100
# iptables -t mangle -A OUTPUT -d 8.8.8.8 -j MARK --set-mark 0x1
Current behaviour:
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
New behaviour:
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv4/netfilter.c')
-rw-r--r-- | net/ipv4/netfilter.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 4c0cf63dd92e..8b201e8095cd 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -40,14 +40,14 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type) fl4.flowi4_flags = flags; rt = ip_route_output_key(net, &fl4); if (IS_ERR(rt)) - return -1; + return PTR_ERR(rt); /* Drop old route. */ skb_dst_drop(skb); skb_dst_set(skb, &rt->dst); if (skb_dst(skb)->error) - return -1; + return skb_dst(skb)->error; #ifdef CONFIG_XFRM if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && @@ -56,7 +56,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type) skb_dst_set(skb, NULL); dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), skb->sk, 0); if (IS_ERR(dst)) - return -1; + return PTR_ERR(dst);; skb_dst_set(skb, dst); } #endif @@ -66,7 +66,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type) if (skb_headroom(skb) < hh_len && pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)), 0, GFP_ATOMIC)) - return -1; + return -ENOMEM; return 0; } |