00411c9186
SVN-Revision: 37262
68 lines
1.8 KiB
Diff
68 lines
1.8 KiB
Diff
--- a/include/net/ip6_fib.h
|
|
+++ b/include/net/ip6_fib.h
|
|
@@ -37,6 +37,7 @@ struct fib6_config {
|
|
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;
|
|
--- a/net/ipv6/route.c
|
|
+++ b/net/ipv6/route.c
|
|
@@ -1333,8 +1333,18 @@ int ip6_route_add(struct fib6_config *cf
|
|
}
|
|
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 @@ static int rtm_to_fib6_config(struct sk_
|
|
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 @@ static int rt6_fill_node(struct net *net
|
|
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))
|