diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index bf8e40af60b0..97c3f61d627b 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1845,24 +1845,30 @@ static int ip6_tnl_fill_forward_path(struct net_device_path_ctx *ctx, struct net_device_path *path) { struct ip6_tnl *t = netdev_priv(ctx->dev); - struct flowi6 fl6 = { - .daddr = t->parms.raddr, - }; struct dst_entry *dst; + struct flowi6 fl6; int err; - if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) { - /* encaplimit option is currently not supported is - * sw-acceleration path. - */ + if (t->parms.flags & (IP6_TNL_F_USE_ORIG_TCLASS | + IP6_TNL_F_USE_ORIG_FLOWLABEL | + IP6_TNL_F_USE_ORIG_FWMARK)) return -EOPNOTSUPP; - } + + if (t->parms.collect_md) + return -EOPNOTSUPP; + + if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) + return -EOPNOTSUPP; + + memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); + fl6.flowi6_mark = t->parms.fwmark; + fl6.flowi6_proto = 0; dst = ip6_route_output(dev_net(ctx->dev), NULL, &fl6); if (!dst->error) { path->type = DEV_PATH_TUN; - path->tun.src_v6 = t->parms.laddr; - path->tun.dst_v6 = t->parms.raddr; + path->tun.src_v6 = fl6.saddr; + path->tun.dst_v6 = fl6.daddr; path->tun.l3_proto = IPPROTO_IPV6; path->dev = ctx->dev; ctx->dev = dst->dev;