Skip to content

Commit efd8570

Browse files
tgrafdavem330
authored andcommitted
route: Set lwtstate for local traffic and cached input dsts
A route on the output path hitting a RTN_LOCAL route will keep the dst associated on its way through the loopback device. On the receive path, the dst_input() call will thus invoke the input handler of the route created in the output path. Thus, lwt redirection for input must be done for dsts allocated in the otuput path as well. Also, if a route is cached in the input path, the allocated dst should respect lwtunnel configuration on the nexthop as well. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 11b3d9c commit efd8570

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

net/ipv4/route.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,19 @@ static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)
16031603
spin_unlock_bh(&fnhe_lock);
16041604
}
16051605

1606+
static void set_lwt_redirect(struct rtable *rth)
1607+
{
1608+
if (lwtunnel_output_redirect(rth->dst.lwtstate)) {
1609+
rth->dst.lwtstate->orig_output = rth->dst.output;
1610+
rth->dst.output = lwtunnel_output;
1611+
}
1612+
1613+
if (lwtunnel_input_redirect(rth->dst.lwtstate)) {
1614+
rth->dst.lwtstate->orig_input = rth->dst.input;
1615+
rth->dst.input = lwtunnel_input;
1616+
}
1617+
}
1618+
16061619
/* called in rcu_read_lock() section */
16071620
static int __mkroute_input(struct sk_buff *skb,
16081621
const struct fib_result *res,
@@ -1692,14 +1705,7 @@ static int __mkroute_input(struct sk_buff *skb,
16921705
rth->dst.input = ip_forward;
16931706

16941707
rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag);
1695-
if (lwtunnel_output_redirect(rth->dst.lwtstate)) {
1696-
rth->dst.lwtstate->orig_output = rth->dst.output;
1697-
rth->dst.output = lwtunnel_output;
1698-
}
1699-
if (lwtunnel_input_redirect(rth->dst.lwtstate)) {
1700-
rth->dst.lwtstate->orig_input = rth->dst.input;
1701-
rth->dst.input = lwtunnel_input;
1702-
}
1708+
set_lwt_redirect(rth);
17031709
skb_dst_set(skb, &rth->dst);
17041710
out:
17051711
err = 0;
@@ -1926,8 +1932,18 @@ out: return err;
19261932
rth->dst.error= -err;
19271933
rth->rt_flags &= ~RTCF_LOCAL;
19281934
}
1935+
19291936
if (do_cache) {
1930-
if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
1937+
struct fib_nh *nh = &FIB_RES_NH(res);
1938+
1939+
rth->dst.lwtstate = lwtstate_get(nh->nh_lwtstate);
1940+
if (lwtunnel_input_redirect(rth->dst.lwtstate)) {
1941+
WARN_ON(rth->dst.input == lwtunnel_input);
1942+
rth->dst.lwtstate->orig_input = rth->dst.input;
1943+
rth->dst.input = lwtunnel_input;
1944+
}
1945+
1946+
if (unlikely(!rt_cache_route(nh, rth))) {
19311947
rth->dst.flags |= DST_NOCACHE;
19321948
rt_add_uncached_list(rth);
19331949
}
@@ -2155,10 +2171,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
21552171
}
21562172

21572173
rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0);
2158-
if (lwtunnel_output_redirect(rth->dst.lwtstate)) {
2159-
rth->dst.lwtstate->orig_output = rth->dst.output;
2160-
rth->dst.output = lwtunnel_output;
2161-
}
2174+
set_lwt_redirect(rth);
21622175

21632176
return rth;
21642177
}

0 commit comments

Comments
 (0)