14#ifndef OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H
15#define OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H
21#include <linux/if_tun.h>
51template <
class TUNMETHODS>
78 Json::Value root(Json::objectValue);
80 root[
"layer"] = Json::Value(
layer.
str());
81 root[
"dev_name"] = Json::Value(
dev_name);
83 root[
"dco"] = Json::Value(
dco);
87 virtual void from_json(
const Json::Value &root,
const std::string &title)
override
131 std::ostream &
os)
override
136 throw tun_linux_error(
"missing config");
175 static const char node[] =
"/dev/net/tun";
181 std::memset(&ifr, 0,
sizeof(ifr));
182 ifr.ifr_flags = IFF_ONE_QUEUE;
183 ifr.ifr_flags |= IFF_NO_PI;
185 ifr.ifr_flags |= IFF_TUN;
187 ifr.ifr_flags |= IFF_TAP;
189 throw tun_layer_error(
"unknown OSI layer");
193 if (fcntl(fd(), F_SETFL, O_NONBLOCK) < 0)
194 throw tun_fcntl_error(
errinfo(errno));
200 ScopedFD ctl_fd(socket(AF_INET, SOCK_DGRAM, 0));
202 if (ctl_fd.defined())
204 std::memset(&netifr, 0,
sizeof(netifr));
205 strcpy(netifr.ifr_name, ifr.ifr_name);
207 if (ioctl(ctl_fd(), SIOCSIFTXQLEN, (
void *)&netifr) < 0)
208 throw tun_tx_queue_len_error(
errinfo(errno));
211 throw tun_tx_queue_len_error(
errinfo(errno));
223 const int max_units = 256;
224 for (
int unit = 0; unit < max_units; ++unit)
226 std::string n = name;
229 if (n.length() < IFNAMSIZ)
230 ::strcpy(ifr.ifr_name, n.c_str());
232 throw tun_name_error();
233 if (ioctl(fd(), TUNSETIFF, (
void *)&ifr) == 0)
236 const int eno = errno;
237 OPENVPN_THROW(tun_ioctl_error,
"failed to open tun device '" << name <<
"' after trying " << max_units <<
" units : " <<
errinfo(eno));
241 if (ioctl(fd(), TUNSETIFF, (
void *)&ifr) < 0)
243 const int eno = errno;
244 OPENVPN_THROW(tun_ioctl_error,
"failed to open tun device '" << name <<
"' : " <<
errinfo(eno));
virtual std::unordered_set< std::string > execute(std::ostream &os)
Executes a sequence of actions and returns marks of failed actions.
static Layer from_str(const std::string &str)
std::string to_string() const
Returns a string representation of the remote address.
RemoteAddress remote_address
std::string tun_iface_name
void open_unit(const std::string &name, struct ifreq &ifr, ScopedFD &fd)
ActionList::Ptr remove_cmds_bypass_gw
bool add_bypass_route(const std::string &address, bool ipv6, std::ostream &os)
void destroy(std::ostream &os) override
ActionListReversed::Ptr remove_cmds
int open_tun(Config *conf)
int establish(const TunBuilderCapture &pull, TunBuilderSetup::Config *config, Stop *stop, std::ostream &os) override
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_THROW(exc, stuff)
void assert_dict(const Json::Value &obj, const TITLE &title)
void to_string(const Json::Value &root, std::string &dest, const NAME &name, const TITLE &title)
void to_int(const Json::Value &root, int &dest, const NAME &name, const TITLE &title)
void to_bool(const Json::Value &root, bool &dest, const NAME &name, const TITLE &title)
std::string get_string(const Json::Value &root, const NAME &name, const TITLE &title)
std::string to_string(const T &t)
Convert a value to a string.
std::string errinfo(ErrorCode err)
virtual void from_json(const Json::Value &root, const std::string &title) override
virtual Json::Value to_json() override
bool add_bypass_routes_on_establish
static const char config[]