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 std::vector<std::string> paths{
"/bin/ip",
"/sbin/ip",
"/usr/bin/ip",
"/usr/sbin/ip"};
64 for (
const auto &path : paths)
66 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>
132 argv.emplace_back(
"a");
133 argv.emplace_back(
"show");
134 argv.emplace_back(
"dev");
135 argv.emplace_back(
dev);
139 template <
typename CALLBACK>
146 argv.emplace_back(
"route");
147 argv.emplace_back(
"get");
148 argv.emplace_back(std::move(dst));
152 std::string
dev =
"tun999";
157 std::string
gw4 =
"10.10.0.1";
159 std::string
addr6 =
"fe80:20c3:aaaa:bbbb::cccc";
160 std::string
route6 =
"fe80:20c3:cccc:dddd::0/64";
161 std::string
gw6 =
"fe80:20c3:aaaa:bbbb:cccc:dddd:eeee:1";
173 ip_a_show_dev([
this, &broadcast](std::vector<std::string> &v,
const std::string &
out,
bool &called)
178 ASSERT_EQ(v[1], addr4 +
"/" + std::to_string(ipv4_prefix_len)) <<
out;
179 ASSERT_EQ(v[3], broadcast.to_string()) <<
out;
187 ip_a_show_dev([
this](std::vector<std::string> &v,
const std::string &
out,
bool &called)
192 ASSERT_EQ(v[1], addr6 +
"/" + std::to_string(ipv6_prefix_len)) <<
out;
200 ip_a_show_dev([
this](std::vector<std::string> &v,
const std::string &
out,
bool &called)
202 if ((v.size() > 1) && (v[1] == dev +
":"))
205 ASSERT_EQ(v[4], std::to_string(mtu)) << out;
221 std::string dst{
"10.110.0.100"};
223 ip_route_get(dst, [
this, &dst](std::vector<std::string> &v,
const std::string &
out,
bool &called)
229 auto expected = std::vector<std::string>{dst,
"via", gw4,
"dev", dev,
"src", addr4};
245 std::string dst{
"fe80:20c3:cccc:dddd:cccc:dddd:eeee:ffff"};
249 std::string dst_trunc{dst};
250 dst_trunc.resize(31);
252 ip_route_get(dst, [
this, &dst, &dst_trunc](std::vector<std::string> &v1,
const std::string &
out,
bool &called)
254 if (v1[0] == dst || v1[0] == dst_trunc)
256 std::string dst_out = (v1[0] == dst) ? dst : dst_trunc;
260 auto expected1 = std::vector<std::string>{dst_out,
"from",
"::",
"via", gw6,
"dev", dev};
261 auto ok1 = (v1 == expected1);
266 auto expected2 = std::vector<std::string>{dst_out,
"via", gw6,
"dev", dev};
267 auto ok2 = (v2 == expected2);
272 EXPECT_EQ(v1, expected1);
273 EXPECT_EQ(v2, expected2);
299 std::string best_iface;
304 ASSERT_EQ(best_gw.
to_string(),
"10.10.10.13");
305 ASSERT_EQ(best_iface, dev);
326 std::string best_iface;
331 ASSERT_EQ(best_gw.
to_string(),
"10.10.0.1");
332 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