aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/route.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 016ed7c22fc9..4f768a4c2907 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -818,7 +818,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
}
static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
- struct flowi6 *fl6, int flags)
+ struct flowi6 *fl6, int flags, bool input)
{
struct fib6_node *fn;
struct rt6_info *rt, *nrt;
@@ -826,8 +826,11 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
int attempts = 3;
int err;
int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
+ int local = RTF_NONEXTHOP;
strict |= flags & RT6_LOOKUP_F_IFACE;
+ if (input)
+ local |= RTF_LOCAL;
relookup:
read_lock_bh(&table->tb6_lock);
@@ -847,7 +850,7 @@ restart:
read_unlock_bh(&table->tb6_lock);
if (!dst_get_neighbour_noref_raw(&rt->dst) &&
- !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL)))
+ !(rt->rt6i_flags & local))
nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
else if (!(rt->dst.flags & DST_HOST))
nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -891,7 +894,7 @@ out2:
static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
struct flowi6 *fl6, int flags)
{
- return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
+ return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags, true);
}
static struct dst_entry *ip6_route_input_lookup(struct net *net,
@@ -924,7 +927,7 @@ void ip6_route_input(struct sk_buff *skb)
static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
struct flowi6 *fl6, int flags)
{
- return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
+ return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags, false);
}
struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,