14#include <sys/capability.h>
25using namespace TunNetlink;
38 argv.emplace_back(
"tuntap");
39 argv.emplace_back(
"add");
40 argv.emplace_back(
"mode");
41 argv.emplace_back(
"tun");
42 argv.emplace_back(std::move(name));
43 system_cmd(argv[0], argv,
nullptr, pipe, 0,
nullptr);
51 argv.emplace_back(
"tuntap");
52 argv.emplace_back(
"delete");
53 argv.emplace_back(
"mode");
54 argv.emplace_back(
"tun");
55 argv.emplace_back(std::move(name));
56 system_cmd(argv[0], argv,
nullptr, pipe, 0,
nullptr);
63 const std::vector<std::string> paths{
"/bin/ip",
"/sbin/ip",
"/usr/bin/ip",
"/usr/sbin/ip"};
64 for (
const auto &path : paths)
66 const std::ifstream
f(path);
73 ASSERT_FALSE(
path_to_ip.empty()) <<
"unable to find ip tool";
78 cap_t cap = cap_get_proc();
79 cap_flag_value_t v = CAP_CLEAR;
80 cap_get_flag(cap, CAP_NET_ADMIN, CAP_EFFECTIVE, &v);
88 GTEST_SKIP() <<
"Need CAP_NET_ADMIN to run this test";
100 template <
typename CALLBACK>
105 ASSERT_EQ(
system_cmd(argv[0], argv,
nullptr, pipe, 0,
nullptr), 0) <<
"failed to run command " << argv[0];
111 const std::string &line = sl.
line_ref();
119 cb(v, pipe.
out, called);
122 ASSERT_TRUE(called) << pipe.
out;
125 template <
typename CALLBACK>
131 argv.emplace_back(
"a");
132 argv.emplace_back(
"show");
133 argv.emplace_back(
"dev");
134 argv.emplace_back(
dev);
138 template <
typename CALLBACK>
144 argv.emplace_back(
"route");
145 argv.emplace_back(
"get");
146 argv.emplace_back(std::move(dst));
150 std::string
dev =
"tun999";
155 std::string
gw4 =
"10.10.0.1";
157 std::string
addr6 =
"fe80:20c3:aaaa:bbbb::cccc";
158 std::string
route6 =
"fe80:20c3:cccc:dddd::0/64";
159 std::string
gw6 =
"fe80:20c3:aaaa:bbbb:cccc:dddd:eeee:1";
171 ip_a_show_dev([
this, &broadcast](std::vector<std::string> &v,
const std::string &
out,
bool &called)
176 ASSERT_EQ(v[1], addr4 +
"/" + std::to_string(ipv4_prefix_len)) <<
out;
177 ASSERT_EQ(v[3], broadcast.to_string()) <<
out;
185 ip_a_show_dev([
this](std::vector<std::string> &v,
const std::string &
out,
bool &called)
190 ASSERT_EQ(v[1], addr6 +
"/" + std::to_string(ipv6_prefix_len)) <<
out;
198 ip_a_show_dev([
this](std::vector<std::string> &v,
const std::string &
out,
bool &called)
200 if ((v.size() > 1) && (v[1] == dev +
":"))
203 ASSERT_EQ(v[4], std::to_string(mtu)) << out;
219 std::string dst{
"10.110.0.100"};
221 ip_route_get(dst, [
this, &dst](std::vector<std::string> &v,
const std::string &
out,
bool &called)
227 auto expected = std::vector<std::string>{dst,
"via", gw4,
"dev", dev,
"src", addr4};
243 std::string dst{
"fe80:20c3:cccc:dddd:cccc:dddd:eeee:ffff"};
247 std::string dst_trunc{dst};
248 dst_trunc.resize(31);
250 ip_route_get(dst, [
this, &dst, &dst_trunc](std::vector<std::string> &v1,
const std::string &
out,
bool &called)
252 if (v1[0] == dst || v1[0] == dst_trunc)
254 const std::string dst_out = (v1[0] == dst) ? dst : dst_trunc;
258 auto expected1 = std::vector<std::string>{dst_out,
"from",
"::",
"via", gw6,
"dev", dev};
259 auto ok1 = (v1 == expected1);
264 auto expected2 = std::vector<std::string>{dst_out,
"via", gw6,
"dev", dev};
265 auto ok2 = (v2 == expected2);
270 EXPECT_EQ(v1, expected1);
271 EXPECT_EQ(v2, expected2);
297 std::string best_iface;
302 ASSERT_EQ(best_gw.
to_string(),
"10.10.10.13");
303 ASSERT_EQ(best_iface, dev);
324 std::string best_iface;
329 ASSERT_EQ(best_gw.
to_string(),
"10.10.0.1");
330 ASSERT_EQ(best_iface, dev);
std::string to_string() const
static Addr from_string(const std::string &ipstr, const TITLE &title)
static Addr from_string(const std::string &ipstr, const TITLE &title)
static int net_addr_add(const std::string &iface, const IPv4::Addr &addr, const unsigned char prefixlen, const IPv4::Addr &broadcast)
static int net_route_best_gw(const IP::Route6 &route, IPv6::Addr &best_gw6, std::string &best_iface, const std::string &iface_to_ignore="")
static int net_iface_up(std::string &iface, bool up)
static int net_iface_mtu_set(std::string &iface, uint32_t mtu)
static int net_route_add(const IP::Route4 &route, const IPv4::Addr &gw, const std::string &iface, const uint32_t table, const int metric)
void add_device(std::string name)
static void SetUpTestSuite()
void remove_device(std::string name)
void ip_route_get(std::string dst, CALLBACK cb)
void cmd(const Argv &argv, CALLBACK cb)
static bool haveCapNetAdmin()
void ip_a_show_dev(CALLBACK cb)
int system_cmd(const std::string &cmd, const Argv &argv, RedirectBase *redir, const Environ *env, const sigset_t *sigmask)
TEST_F(IpHelperTest, TestAddRoute4)
static std::string path_to_ip
static std::stringstream out