diff options
-rw-r--r-- | net/ipv6/route.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25b0beda4331..25476e7e708b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1169,6 +1169,8 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1169 | 1169 | ||
1170 | if (addr_type & IPV6_ADDR_MULTICAST) | 1170 | if (addr_type & IPV6_ADDR_MULTICAST) |
1171 | rt->dst.input = ip6_mc_input; | 1171 | rt->dst.input = ip6_mc_input; |
1172 | else if (cfg->fc_flags & RTF_LOCAL) | ||
1173 | rt->dst.input = ip6_input; | ||
1172 | else | 1174 | else |
1173 | rt->dst.input = ip6_forward; | 1175 | rt->dst.input = ip6_forward; |
1174 | 1176 | ||
@@ -1190,7 +1192,8 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1190 | they would result in kernel looping; promote them to reject routes | 1192 | they would result in kernel looping; promote them to reject routes |
1191 | */ | 1193 | */ |
1192 | if ((cfg->fc_flags & RTF_REJECT) || | 1194 | if ((cfg->fc_flags & RTF_REJECT) || |
1193 | (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { | 1195 | (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK) |
1196 | && !(cfg->fc_flags&RTF_LOCAL))) { | ||
1194 | /* hold loopback dev/idev if we haven't done so. */ | 1197 | /* hold loopback dev/idev if we haven't done so. */ |
1195 | if (dev != net->loopback_dev) { | 1198 | if (dev != net->loopback_dev) { |
1196 | if (dev) { | 1199 | if (dev) { |
@@ -2082,6 +2085,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2082 | if (rtm->rtm_type == RTN_UNREACHABLE) | 2085 | if (rtm->rtm_type == RTN_UNREACHABLE) |
2083 | cfg->fc_flags |= RTF_REJECT; | 2086 | cfg->fc_flags |= RTF_REJECT; |
2084 | 2087 | ||
2088 | if (rtm->rtm_type == RTN_LOCAL) | ||
2089 | cfg->fc_flags |= RTF_LOCAL; | ||
2090 | |||
2085 | cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; | 2091 | cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; |
2086 | cfg->fc_nlinfo.nlh = nlh; | 2092 | cfg->fc_nlinfo.nlh = nlh; |
2087 | cfg->fc_nlinfo.nl_net = sock_net(skb->sk); | 2093 | cfg->fc_nlinfo.nl_net = sock_net(skb->sk); |
@@ -2202,6 +2208,8 @@ static int rt6_fill_node(struct net *net, | |||
2202 | NLA_PUT_U32(skb, RTA_TABLE, table); | 2208 | NLA_PUT_U32(skb, RTA_TABLE, table); |
2203 | if (rt->rt6i_flags&RTF_REJECT) | 2209 | if (rt->rt6i_flags&RTF_REJECT) |
2204 | rtm->rtm_type = RTN_UNREACHABLE; | 2210 | rtm->rtm_type = RTN_UNREACHABLE; |
2211 | else if (rt->rt6i_flags&RTF_LOCAL) | ||
2212 | rtm->rtm_type = RTN_LOCAL; | ||
2205 | else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) | 2213 | else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) |
2206 | rtm->rtm_type = RTN_LOCAL; | 2214 | rtm->rtm_type = RTN_LOCAL; |
2207 | else | 2215 | else |