From a069e6701e7b5235c14e40a1561c240015f16c7d Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Wed, 5 Sep 2012 02:12:42 +0000 Subject: [PATCH] --- yaml --- r: 327821 b: refs/heads/master c: ef2c7d7b59708d54213c7556a82d14de9a7e4475 h: refs/heads/master i: 327819: 4dea18d6361c5984c7a167b7ef3e51ef0c79476a v: v3 --- [refs] | 2 +- trunk/include/net/ip6_fib.h | 1 + trunk/net/ipv6/route.c | 32 ++++++++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index fcb51d2c76f5..2b36555a7da1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d6b6d987787876fd381bfeda310c6682d425c0a2 +refs/heads/master: ef2c7d7b59708d54213c7556a82d14de9a7e4475 diff --git a/trunk/include/net/ip6_fib.h b/trunk/include/net/ip6_fib.h index 0fedbd8d747a..cd64cf35a49f 100644 --- a/trunk/include/net/ip6_fib.h +++ b/trunk/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; diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 0ddf2d132e7f..fa264447a751 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -1463,8 +1463,18 @@ int ip6_route_add(struct fib6_config *cfg) } 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; } @@ -2261,8 +2271,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, 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) @@ -2391,8 +2404,19 @@ static int rt6_fill_node(struct net *net, rtm->rtm_table = table; if (nla_put_u32(skb, RTA_TABLE, table)) goto nla_put_failure; - 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))