Index: linux-3.3.8/include/net/ip6_fib.h =================================================================== --- linux-3.3.8.orig/include/net/ip6_fib.h 2013-06-10 20:53:49.093355283 +0200 +++ linux-3.3.8/include/net/ip6_fib.h 2013-06-10 20:53:49.085355283 +0200 @@ -37,6 +37,7 @@ int fc_ifindex; u32 fc_flags; u32 fc_protocol; + u32 fc_type; /* only 8 bits are used */ struct in6_addr fc_dst; struct in6_addr fc_src; Index: linux-3.3.8/net/ipv6/route.c =================================================================== --- linux-3.3.8.orig/net/ipv6/route.c 2013-06-10 20:53:49.093355283 +0200 +++ linux-3.3.8/net/ipv6/route.c 2013-06-10 20:53:49.089355283 +0200 @@ -1333,8 +1333,18 @@ } rt->dst.output = ip6_pkt_discard_out; rt->dst.input = ip6_pkt_discard; - rt->dst.error = -ENETUNREACH; rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; + switch (cfg->fc_type) { + case RTN_BLACKHOLE: + rt->dst.error = -EINVAL; + break; + case RTN_PROHIBIT: + rt->dst.error = -EACCES; + break; + default: + rt->dst.error = -ENETUNREACH; + break; + } goto install_route; } @@ -2265,8 +2275,11 @@ cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_flags = RTF_UP; cfg->fc_protocol = rtm->rtm_protocol; + cfg->fc_type = rtm->rtm_type; - if (rtm->rtm_type == RTN_UNREACHABLE) + if (rtm->rtm_type == RTN_UNREACHABLE || + rtm->rtm_type == RTN_BLACKHOLE || + rtm->rtm_type == RTN_PROHIBIT) cfg->fc_flags |= RTF_REJECT; if (rtm->rtm_type == RTN_LOCAL) @@ -2396,8 +2409,19 @@ table = RT6_TABLE_UNSPEC; rtm->rtm_table = table; NLA_PUT_U32(skb, RTA_TABLE, table); - if (rt->rt6i_flags & RTF_REJECT) - rtm->rtm_type = RTN_UNREACHABLE; + if (rt->rt6i_flags & RTF_REJECT) { + switch (rt->dst.error) { + case -EINVAL: + rtm->rtm_type = RTN_BLACKHOLE; + break; + case -EACCES: + rtm->rtm_type = RTN_PROHIBIT; + break; + default: + rtm->rtm_type = RTN_UNREACHABLE; + break; + } + } else if (rt->rt6i_flags & RTF_LOCAL) rtm->rtm_type = RTN_LOCAL; else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))