It's safe as long as the mystruct class is properly written, which means it supports copy construction and assignment and/or moving, and proper destruction, with the implied value semantics.
Put another way: "returning a vector" thing isn't the hard part here, it's making sure if you've got one T t1; in any valid state, then you can say T t2(t1); and/or T t3; t3 = t1; and/or let any T go out of scope / be deleted and nothing bad or unexpected will happen. If your T works for those scenarios, all's good to use it in a vector<T>, even for returning by value from a function.
But which structs are safe for that? mystruct is ok to copy/move construct/assign and destroy if it's careful to only make non-static data members one of the following types, and any base classes do similarly:
simple data types like int, double, bool etc.
self-managing types with value semantics, whether you wrote them yourself or they're provided by the Standard library or another library - e.g. std::string, std::map, std::vector, std::list etc. these know how to copy/move themselves properly
arrays of such types
std::shared_ptr to data you do actually want shared ownership of, or std::unique_ptr<> to data that can be moved but not copied
references, if it makes sense for a copy of the object to refer to the same place
other structs and/or classes whose members and base classes satisfy the above conditions
But not raw pointers (unless to some deliberately shared data with a lifetime greater than the objects, e.g. a static const variable or string literal): for new/new[]-ed data the object's meant to manage lifetime for, you need to write your own copy constructor and/or move constructor, copy assignment and/or move assignment operator, and destructor. It's usually much easier and better to use a std::shared_ptr<> or std::unique_ptr<> instead.