summaryrefslogtreecommitdiff
path: root/net/ipv6/netfilter/ip6table_mangle.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2013-04-05 06:41:11 +0000
committerPablo Neira Ayuso <pablo@netfilter.org>2013-04-08 12:34:01 +0200
commit58e35d1471287c59b9749fb82f04c628c36b9994 (patch)
treea09f82319c6a2599f8c0ab9f94913aa4faf58448 /net/ipv6/netfilter/ip6table_mangle.c
parentc9e1673a0accf086dfce9b501d8bcb4ec6bbc1e9 (diff)
netfilter: ipv6: propagate routing errors from ip6_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. # ip -6 r a unreachable default table 100 # ip -6 ru add fwmark 0x1 lookup 100 # ip6tables -t mangle -A OUTPUT -d 2001:4860:4860::8888 -j MARK --set-mark 0x1 Old behaviour: PING 2001:4860:4860::8888(2001:4860:4860::8888) 56 data bytes ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted New behaviour: PING 2001:4860:4860::8888(2001:4860:4860::8888) 56 data bytes 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/ipv6/netfilter/ip6table_mangle.c')
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 6134a1ebfb1b..e075399d8b72 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -38,7 +38,7 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
struct in6_addr saddr, daddr;
u_int8_t hop_limit;
u_int32_t flowlabel, mark;
-
+ int err;
#if 0
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
@@ -65,8 +65,11 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out)
!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
skb->mark != mark ||
ipv6_hdr(skb)->hop_limit != hop_limit ||
- flowlabel != *((u_int32_t *)ipv6_hdr(skb))))
- return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP;
+ flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
+ err = ip6_route_me_harder(skb);
+ if (err < 0)
+ ret = NF_DROP_ERR(err);
+ }
return ret;
}