aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNikola Forró <nforro@redhat.com>2015-09-17 10:01:32 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-21 00:45:08 -0400
commit0315e382704817b279e5693dca8ab9d89aa20b3f (patch)
tree25effda1de2f346cd70a64483193eb81d6edd771 /net
parentba5ca7848be05db6235aeb703586b821aa00e381 (diff)
net: Fix behaviour of unreachable, blackhole and prohibit routes
Man page of ip-route(8) says following about route types: unreachable - these destinations are unreachable. Packets are dis‐ carded and the ICMP message host unreachable is generated. The local senders get an EHOSTUNREACH error. blackhole - these destinations are unreachable. Packets are dis‐ carded silently. The local senders get an EINVAL error. prohibit - these destinations are unreachable. Packets are discarded and the ICMP message communication administratively prohibited is generated. The local senders get an EACCES error. In the inet6 address family, this was correct, except the local senders got ENETUNREACH error instead of EHOSTUNREACH in case of unreachable route. In the inet address family, all three route types generated ICMP message net unreachable, and the local senders got ENETUNREACH error. In both address families all three route types now behave consistently with documentation. Signed-off-by: Nikola Forró <nforro@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/route.c6
-rw-r--r--net/ipv6/route.c4
2 files changed, 7 insertions, 3 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5f4a5565ad8b..c6ad99ad0ffb 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2045,6 +2045,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
2045 struct fib_result res; 2045 struct fib_result res;
2046 struct rtable *rth; 2046 struct rtable *rth;
2047 int orig_oif; 2047 int orig_oif;
2048 int err = -ENETUNREACH;
2048 2049
2049 res.tclassid = 0; 2050 res.tclassid = 0;
2050 res.fi = NULL; 2051 res.fi = NULL;
@@ -2153,7 +2154,8 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
2153 goto make_route; 2154 goto make_route;
2154 } 2155 }
2155 2156
2156 if (fib_lookup(net, fl4, &res, 0)) { 2157 err = fib_lookup(net, fl4, &res, 0);
2158 if (err) {
2157 res.fi = NULL; 2159 res.fi = NULL;
2158 res.table = NULL; 2160 res.table = NULL;
2159 if (fl4->flowi4_oif) { 2161 if (fl4->flowi4_oif) {
@@ -2181,7 +2183,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
2181 res.type = RTN_UNICAST; 2183 res.type = RTN_UNICAST;
2182 goto make_route; 2184 goto make_route;
2183 } 2185 }
2184 rth = ERR_PTR(-ENETUNREACH); 2186 rth = ERR_PTR(err);
2185 goto out; 2187 goto out;
2186 } 2188 }
2187 2189
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d5fa50297f80..f204089e854c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1885,9 +1885,11 @@ int ip6_route_info_create(struct fib6_config *cfg, struct rt6_info **rt_ret)
1885 rt->dst.input = ip6_pkt_prohibit; 1885 rt->dst.input = ip6_pkt_prohibit;
1886 break; 1886 break;
1887 case RTN_THROW: 1887 case RTN_THROW:
1888 case RTN_UNREACHABLE:
1888 default: 1889 default:
1889 rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN 1890 rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
1890 : -ENETUNREACH; 1891 : (cfg->fc_type == RTN_UNREACHABLE)
1892 ? -EHOSTUNREACH : -ENETUNREACH;
1891 rt->dst.output = ip6_pkt_discard_out; 1893 rt->dst.output = ip6_pkt_discard_out;
1892 rt->dst.input = ip6_pkt_discard; 1894 rt->dst.input = ip6_pkt_discard;
1893 break; 1895 break;