tun.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. // SPDX-License-Identifier: GPL-2.0
  2. #define _GNU_SOURCE
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <linux/if_tun.h>
  10. #include <sys/ioctl.h>
  11. #include <sys/socket.h>
  12. #include "kselftest_harness.h"
  13. #include "tuntap_helpers.h"
  14. static const char param_dev_geneve_name[] = "geneve1";
  15. static unsigned char param_hwaddr_outer_dst[] = { 0x00, 0xfe, 0x98,
  16. 0x14, 0x22, 0x42 };
  17. static unsigned char param_hwaddr_outer_src[] = { 0x00, 0xfe, 0x98,
  18. 0x94, 0xd2, 0x43 };
  19. static unsigned char param_hwaddr_inner_dst[] = { 0x00, 0xfe, 0x98,
  20. 0x94, 0x22, 0xcc };
  21. static unsigned char param_hwaddr_inner_src[] = { 0x00, 0xfe, 0x98,
  22. 0x94, 0xd2, 0xdd };
  23. static struct in_addr param_ipaddr4_outer_dst = {
  24. __constant_htonl(0xac100001),
  25. };
  26. static struct in_addr param_ipaddr4_outer_src = {
  27. __constant_htonl(0xac100002),
  28. };
  29. static struct in_addr param_ipaddr4_inner_dst = {
  30. __constant_htonl(0xac100101),
  31. };
  32. static struct in_addr param_ipaddr4_inner_src = {
  33. __constant_htonl(0xac100102),
  34. };
  35. static struct in6_addr param_ipaddr6_outer_dst = {
  36. { { 0x20, 0x02, 0x0d, 0xb8, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
  37. };
  38. static struct in6_addr param_ipaddr6_outer_src = {
  39. { { 0x20, 0x02, 0x0d, 0xb8, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 } },
  40. };
  41. static struct in6_addr param_ipaddr6_inner_dst = {
  42. { { 0x20, 0x02, 0x0d, 0xb8, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
  43. };
  44. static struct in6_addr param_ipaddr6_inner_src = {
  45. { { 0x20, 0x02, 0x0d, 0xb8, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 } },
  46. };
  47. #ifndef BIT
  48. #define BIT(nr) (1UL << (nr))
  49. #endif
  50. #define VN_ID 1
  51. #define VN_PORT 4789
  52. #define UDP_SRC_PORT 22
  53. #define UDP_DST_PORT 48878
  54. #define IPPREFIX_LEN 24
  55. #define IP6PREFIX_LEN 64
  56. #define TIMEOUT_SEC 10
  57. #define TIMEOUT_USEC 100000
  58. #define MAX_RETRIES 20
  59. #define UDP_TUNNEL_GENEVE_4IN4 0x01
  60. #define UDP_TUNNEL_GENEVE_6IN4 0x02
  61. #define UDP_TUNNEL_GENEVE_4IN6 0x04
  62. #define UDP_TUNNEL_GENEVE_6IN6 0x08
  63. #define UDP_TUNNEL_MAX_SEGMENTS BIT(7)
  64. #define UDP_TUNNEL_OUTER_IPV4 (UDP_TUNNEL_GENEVE_4IN4 | UDP_TUNNEL_GENEVE_6IN4)
  65. #define UDP_TUNNEL_INNER_IPV4 (UDP_TUNNEL_GENEVE_4IN4 | UDP_TUNNEL_GENEVE_4IN6)
  66. #define UDP_TUNNEL_GENEVE_4IN4_HDRLEN \
  67. (ETH_HLEN + 2 * sizeof(struct iphdr) + GENEVE_HLEN + \
  68. 2 * sizeof(struct udphdr))
  69. #define UDP_TUNNEL_GENEVE_6IN6_HDRLEN \
  70. (ETH_HLEN + 2 * sizeof(struct ipv6hdr) + GENEVE_HLEN + \
  71. 2 * sizeof(struct udphdr))
  72. #define UDP_TUNNEL_GENEVE_4IN6_HDRLEN \
  73. (ETH_HLEN + sizeof(struct iphdr) + sizeof(struct ipv6hdr) + \
  74. GENEVE_HLEN + 2 * sizeof(struct udphdr))
  75. #define UDP_TUNNEL_GENEVE_6IN4_HDRLEN \
  76. (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct iphdr) + \
  77. GENEVE_HLEN + 2 * sizeof(struct udphdr))
  78. #define UDP_TUNNEL_HDRLEN(type) \
  79. ((type) == UDP_TUNNEL_GENEVE_4IN4 ? UDP_TUNNEL_GENEVE_4IN4_HDRLEN : \
  80. (type) == UDP_TUNNEL_GENEVE_6IN6 ? UDP_TUNNEL_GENEVE_6IN6_HDRLEN : \
  81. (type) == UDP_TUNNEL_GENEVE_4IN6 ? UDP_TUNNEL_GENEVE_4IN6_HDRLEN : \
  82. (type) == UDP_TUNNEL_GENEVE_6IN4 ? UDP_TUNNEL_GENEVE_6IN4_HDRLEN : \
  83. 0)
  84. #define UDP_TUNNEL_MSS(type) (ETH_DATA_LEN - UDP_TUNNEL_HDRLEN(type))
  85. #define UDP_TUNNEL_MAX(type, is_tap) \
  86. (ETH_MAX_MTU - UDP_TUNNEL_HDRLEN(type) - ((is_tap) ? ETH_HLEN : 0))
  87. #define TUN_VNET_TNL_SIZE sizeof(struct virtio_net_hdr_v1_hash_tunnel)
  88. #define MAX_VNET_TUNNEL_PACKET_SZ \
  89. (TUN_VNET_TNL_SIZE + ETH_HLEN + UDP_TUNNEL_GENEVE_6IN6_HDRLEN + \
  90. ETH_MAX_MTU)
  91. struct geneve_setup_config {
  92. int family;
  93. union {
  94. struct in_addr r4;
  95. struct in6_addr r6;
  96. } remote;
  97. __be32 vnid;
  98. __be16 vnport;
  99. unsigned char hwaddr[6];
  100. uint8_t csum;
  101. };
  102. static int tun_attach(int fd, char *dev)
  103. {
  104. struct ifreq ifr;
  105. memset(&ifr, 0, sizeof(ifr));
  106. strcpy(ifr.ifr_name, dev);
  107. ifr.ifr_flags = IFF_ATTACH_QUEUE;
  108. return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
  109. }
  110. static int tun_detach(int fd, char *dev)
  111. {
  112. struct ifreq ifr;
  113. memset(&ifr, 0, sizeof(ifr));
  114. strcpy(ifr.ifr_name, dev);
  115. ifr.ifr_flags = IFF_DETACH_QUEUE;
  116. return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
  117. }
  118. static int tun_alloc(char *dev)
  119. {
  120. struct ifreq ifr;
  121. int fd, err;
  122. fd = open("/dev/net/tun", O_RDWR);
  123. if (fd < 0) {
  124. fprintf(stderr, "can't open tun: %s\n", strerror(errno));
  125. return fd;
  126. }
  127. memset(&ifr, 0, sizeof(ifr));
  128. strcpy(ifr.ifr_name, dev);
  129. ifr.ifr_flags = IFF_TAP | IFF_NAPI | IFF_MULTI_QUEUE;
  130. err = ioctl(fd, TUNSETIFF, (void *)&ifr);
  131. if (err < 0) {
  132. fprintf(stderr, "can't TUNSETIFF: %s\n", strerror(errno));
  133. close(fd);
  134. return err;
  135. }
  136. strcpy(dev, ifr.ifr_name);
  137. return fd;
  138. }
  139. static int tun_delete(char *dev)
  140. {
  141. return ip_link_del(dev);
  142. }
  143. static int tun_open(char *dev, const int flags, const int hdrlen,
  144. const int features, const unsigned char *mac_addr)
  145. {
  146. struct ifreq ifr = { 0 };
  147. int fd, sk = -1;
  148. fd = open("/dev/net/tun", O_RDWR);
  149. if (fd < 0) {
  150. perror("open");
  151. return -1;
  152. }
  153. ifr.ifr_flags = flags;
  154. if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) {
  155. perror("ioctl(TUNSETIFF)");
  156. goto err;
  157. }
  158. strcpy(dev, ifr.ifr_name);
  159. if (hdrlen > 0) {
  160. if (ioctl(fd, TUNSETVNETHDRSZ, &hdrlen) < 0) {
  161. perror("ioctl(TUNSETVNETHDRSZ)");
  162. goto err;
  163. }
  164. }
  165. if (features) {
  166. if (ioctl(fd, TUNSETOFFLOAD, features) < 0) {
  167. perror("ioctl(TUNSETOFFLOAD)");
  168. goto err;
  169. }
  170. }
  171. sk = socket(PF_INET, SOCK_DGRAM, 0);
  172. if (sk < 0) {
  173. perror("socket");
  174. goto err;
  175. }
  176. if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
  177. perror("ioctl(SIOCGIFFLAGS)");
  178. goto err;
  179. }
  180. ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
  181. if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
  182. perror("ioctl(SIOCSIFFLAGS)");
  183. goto err;
  184. }
  185. if (mac_addr && flags & IFF_TAP) {
  186. ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
  187. memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETH_ALEN);
  188. if (ioctl(sk, SIOCSIFHWADDR, &ifr) < 0) {
  189. perror("ioctl(SIOCSIFHWADDR)");
  190. goto err;
  191. }
  192. }
  193. out:
  194. if (sk >= 0)
  195. close(sk);
  196. return fd;
  197. err:
  198. close(fd);
  199. fd = -1;
  200. goto out;
  201. }
  202. static size_t sockaddr_len(int family)
  203. {
  204. return (family == AF_INET) ? sizeof(struct sockaddr_in) :
  205. sizeof(struct sockaddr_in6);
  206. }
  207. static int geneve_fill_newlink(struct rt_link_newlink_req *req, void *data)
  208. {
  209. struct geneve_setup_config *cfg = data;
  210. #define SET_GENEVE_REMOTE rt_link_newlink_req_set_linkinfo_data_geneve_remote
  211. #define SET_GENEVE_REMOTE6 rt_link_newlink_req_set_linkinfo_data_geneve_remote6
  212. rt_link_newlink_req_set_address(req, cfg->hwaddr, ETH_ALEN);
  213. rt_link_newlink_req_set_linkinfo_data_geneve_id(req, cfg->vnid);
  214. rt_link_newlink_req_set_linkinfo_data_geneve_port(req, cfg->vnport);
  215. rt_link_newlink_req_set_linkinfo_data_geneve_udp_csum(req, cfg->csum);
  216. if (cfg->family == AF_INET)
  217. SET_GENEVE_REMOTE(req, cfg->remote.r4.s_addr);
  218. else
  219. SET_GENEVE_REMOTE6(req, &cfg->remote.r6,
  220. sizeof(cfg->remote.r6));
  221. return 0;
  222. }
  223. static int geneve_create(const char *dev, int family, void *remote,
  224. void *hwaddr)
  225. {
  226. struct geneve_setup_config geneve;
  227. memset(&geneve, 0, sizeof(geneve));
  228. geneve.vnid = VN_ID;
  229. geneve.vnport = htons(VN_PORT);
  230. geneve.csum = 1;
  231. geneve.family = family;
  232. if (family == AF_INET)
  233. memcpy(&geneve.remote.r4, remote, sizeof(struct in_addr));
  234. else
  235. memcpy(&geneve.remote.r6, remote, sizeof(struct in6_addr));
  236. memcpy(geneve.hwaddr, hwaddr, ETH_ALEN);
  237. return ip_link_add(dev, "geneve", geneve_fill_newlink, (void *)&geneve);
  238. }
  239. static int set_pmtu_discover(int fd, bool is_ipv4)
  240. {
  241. int level, name, val;
  242. if (is_ipv4) {
  243. level = SOL_IP;
  244. name = IP_MTU_DISCOVER;
  245. val = IP_PMTUDISC_DO;
  246. } else {
  247. level = SOL_IPV6;
  248. name = IPV6_MTU_DISCOVER;
  249. val = IPV6_PMTUDISC_DO;
  250. }
  251. return setsockopt(fd, level, name, &val, sizeof(val));
  252. }
  253. static int udp_socket_open(struct sockaddr_storage *ssa, bool do_frag,
  254. bool do_connect, struct sockaddr_storage *dsa)
  255. {
  256. struct timeval to = { .tv_sec = TIMEOUT_SEC };
  257. int fd, family = ssa->ss_family;
  258. int salen = sockaddr_len(family);
  259. fd = socket(family, SOCK_DGRAM, 0);
  260. if (fd < 0)
  261. return -1;
  262. if (bind(fd, (struct sockaddr *)ssa, salen) < 0) {
  263. perror("bind");
  264. goto err;
  265. }
  266. if (do_connect && connect(fd, (struct sockaddr *)dsa, salen) < 0) {
  267. perror("connect");
  268. goto err;
  269. }
  270. if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to)) < 0) {
  271. perror("setsockopt(SO_RCVTIMEO)");
  272. goto err;
  273. }
  274. if (!do_frag && set_pmtu_discover(fd, family == AF_INET) < 0) {
  275. perror("set_pmtu_discover");
  276. goto err;
  277. }
  278. return fd;
  279. err:
  280. close(fd);
  281. return -1;
  282. }
  283. static void parse_route_rsp(struct rt_route_getroute_rsp *rsp, void *rtm_type)
  284. {
  285. *(uint8_t *)rtm_type = rsp->_hdr.rtm_type;
  286. }
  287. static int ip_route_check(const char *intf, int family, void *addr)
  288. {
  289. uint8_t rtm_type, table = RT_TABLE_LOCAL;
  290. int retries = MAX_RETRIES;
  291. while (retries-- > 0) {
  292. if (ip_route_get(intf, family, table, addr, parse_route_rsp,
  293. &rtm_type) == 0 &&
  294. rtm_type == RTN_LOCAL)
  295. break;
  296. usleep(TIMEOUT_USEC);
  297. }
  298. if (retries < 0)
  299. return -1;
  300. return 0;
  301. }
  302. static int send_gso_udp_msg(int socket, struct sockaddr_storage *addr,
  303. uint8_t *send_buf, int send_len, int gso_size)
  304. {
  305. char control[CMSG_SPACE(sizeof(uint16_t))] = { 0 };
  306. int alen = sockaddr_len(addr->ss_family);
  307. struct msghdr msg = { 0 };
  308. struct iovec iov = { 0 };
  309. int ret;
  310. iov.iov_base = send_buf;
  311. iov.iov_len = send_len;
  312. msg.msg_iov = &iov;
  313. msg.msg_iovlen = 1;
  314. msg.msg_name = addr;
  315. msg.msg_namelen = alen;
  316. if (gso_size > 0) {
  317. struct cmsghdr *cmsg;
  318. msg.msg_control = control;
  319. msg.msg_controllen = sizeof(control);
  320. cmsg = CMSG_FIRSTHDR(&msg);
  321. cmsg->cmsg_level = SOL_UDP;
  322. cmsg->cmsg_type = UDP_SEGMENT;
  323. cmsg->cmsg_len = CMSG_LEN(sizeof(uint16_t));
  324. *(uint16_t *)CMSG_DATA(cmsg) = gso_size;
  325. }
  326. ret = sendmsg(socket, &msg, 0);
  327. if (ret < 0)
  328. perror("sendmsg");
  329. return ret;
  330. }
  331. static int validate_hdrlen(uint8_t **cur, int *len, int x)
  332. {
  333. if (*len < x)
  334. return -1;
  335. *cur += x;
  336. *len -= x;
  337. return 0;
  338. }
  339. static int parse_udp_tunnel_vnet_packet(uint8_t *buf, int len, int tunnel_type,
  340. bool is_tap)
  341. {
  342. struct ipv6hdr *iph6;
  343. struct udphdr *udph;
  344. struct iphdr *iph4;
  345. uint8_t *cur = buf;
  346. if (validate_hdrlen(&cur, &len, TUN_VNET_TNL_SIZE))
  347. return -1;
  348. if (is_tap) {
  349. if (validate_hdrlen(&cur, &len, ETH_HLEN))
  350. return -1;
  351. }
  352. if (tunnel_type & UDP_TUNNEL_OUTER_IPV4) {
  353. iph4 = (struct iphdr *)cur;
  354. if (validate_hdrlen(&cur, &len, sizeof(struct iphdr)))
  355. return -1;
  356. if (iph4->version != 4 || iph4->protocol != IPPROTO_UDP)
  357. return -1;
  358. } else {
  359. iph6 = (struct ipv6hdr *)cur;
  360. if (validate_hdrlen(&cur, &len, sizeof(struct ipv6hdr)))
  361. return -1;
  362. if (iph6->version != 6 || iph6->nexthdr != IPPROTO_UDP)
  363. return -1;
  364. }
  365. udph = (struct udphdr *)cur;
  366. if (validate_hdrlen(&cur, &len, sizeof(struct udphdr)))
  367. return -1;
  368. if (ntohs(udph->dest) != VN_PORT)
  369. return -1;
  370. if (validate_hdrlen(&cur, &len, GENEVE_HLEN))
  371. return -1;
  372. if (validate_hdrlen(&cur, &len, ETH_HLEN))
  373. return -1;
  374. if (tunnel_type & UDP_TUNNEL_INNER_IPV4) {
  375. iph4 = (struct iphdr *)cur;
  376. if (validate_hdrlen(&cur, &len, sizeof(struct iphdr)))
  377. return -1;
  378. if (iph4->version != 4 || iph4->protocol != IPPROTO_UDP)
  379. return -1;
  380. } else {
  381. iph6 = (struct ipv6hdr *)cur;
  382. if (validate_hdrlen(&cur, &len, sizeof(struct ipv6hdr)))
  383. return -1;
  384. if (iph6->version != 6 || iph6->nexthdr != IPPROTO_UDP)
  385. return -1;
  386. }
  387. udph = (struct udphdr *)cur;
  388. if (validate_hdrlen(&cur, &len, sizeof(struct udphdr)))
  389. return -1;
  390. if (ntohs(udph->dest) != UDP_DST_PORT)
  391. return -1;
  392. return len;
  393. }
  394. FIXTURE(tun)
  395. {
  396. char ifname[IFNAMSIZ];
  397. int fd, fd2;
  398. };
  399. FIXTURE_SETUP(tun)
  400. {
  401. memset(self->ifname, 0, sizeof(self->ifname));
  402. self->fd = tun_alloc(self->ifname);
  403. ASSERT_GE(self->fd, 0);
  404. self->fd2 = tun_alloc(self->ifname);
  405. ASSERT_GE(self->fd2, 0);
  406. }
  407. FIXTURE_TEARDOWN(tun)
  408. {
  409. if (self->fd >= 0)
  410. close(self->fd);
  411. if (self->fd2 >= 0)
  412. close(self->fd2);
  413. }
  414. TEST_F(tun, delete_detach_close)
  415. {
  416. EXPECT_EQ(tun_delete(self->ifname), 0);
  417. EXPECT_EQ(tun_detach(self->fd, self->ifname), -1);
  418. EXPECT_EQ(errno, 22);
  419. }
  420. TEST_F(tun, detach_delete_close)
  421. {
  422. EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
  423. EXPECT_EQ(tun_delete(self->ifname), 0);
  424. }
  425. TEST_F(tun, detach_close_delete)
  426. {
  427. EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
  428. close(self->fd);
  429. self->fd = -1;
  430. EXPECT_EQ(tun_delete(self->ifname), 0);
  431. }
  432. TEST_F(tun, reattach_delete_close)
  433. {
  434. EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
  435. EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
  436. EXPECT_EQ(tun_delete(self->ifname), 0);
  437. }
  438. TEST_F(tun, reattach_close_delete)
  439. {
  440. EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
  441. EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
  442. close(self->fd);
  443. self->fd = -1;
  444. EXPECT_EQ(tun_delete(self->ifname), 0);
  445. }
  446. FIXTURE(tun_vnet_udptnl)
  447. {
  448. char ifname[IFNAMSIZ];
  449. int fd, sock;
  450. };
  451. FIXTURE_VARIANT(tun_vnet_udptnl)
  452. {
  453. int tunnel_type;
  454. int gso_size;
  455. int data_size;
  456. int r_num_mss;
  457. bool is_tap, no_gso;
  458. };
  459. /* clang-format off */
  460. #define TUN_VNET_UDPTNL_VARIANT_ADD(type, desc) \
  461. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_1byte) { \
  462. /* no GSO: send a single byte */ \
  463. .tunnel_type = type, \
  464. .data_size = 1, \
  465. .r_num_mss = 1, \
  466. .is_tap = true, \
  467. .no_gso = true, \
  468. }; \
  469. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_1mss) { \
  470. /* no GSO: send a single MSS, fall back to no GSO */ \
  471. .tunnel_type = type, \
  472. .data_size = UDP_TUNNEL_MSS(type), \
  473. .r_num_mss = 1, \
  474. .is_tap = true, \
  475. .no_gso = true, \
  476. }; \
  477. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_nogsosz_gtmss) { \
  478. /* no GSO: send a single MSS + 1B: fail */ \
  479. .tunnel_type = type, \
  480. .data_size = UDP_TUNNEL_MSS(type) + 1, \
  481. .r_num_mss = 1, \
  482. .is_tap = true, \
  483. .no_gso = true, \
  484. }; \
  485. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_1byte) { \
  486. /* GSO: send 1 byte, gso 1 byte, fall back to no GSO */ \
  487. .tunnel_type = type, \
  488. .gso_size = 1, \
  489. .data_size = 1, \
  490. .r_num_mss = 1, \
  491. .is_tap = true, \
  492. .no_gso = true, \
  493. }; \
  494. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_1mss) { \
  495. /* send a single MSS: fall back to no GSO */ \
  496. .tunnel_type = type, \
  497. .gso_size = UDP_TUNNEL_MSS(type), \
  498. .data_size = UDP_TUNNEL_MSS(type), \
  499. .r_num_mss = 1, \
  500. .is_tap = true, \
  501. .no_gso = true, \
  502. }; \
  503. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_ltgso) { \
  504. /* data <= MSS < gso: will fall back to no GSO */ \
  505. .tunnel_type = type, \
  506. .gso_size = UDP_TUNNEL_MSS(type) + 1, \
  507. .data_size = UDP_TUNNEL_MSS(type), \
  508. .r_num_mss = 1, \
  509. .is_tap = true, \
  510. .no_gso = true, \
  511. }; \
  512. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_gtgso) { \
  513. /* GSO: a single MSS + 1B */ \
  514. .tunnel_type = type, \
  515. .gso_size = UDP_TUNNEL_MSS(type), \
  516. .data_size = UDP_TUNNEL_MSS(type) + 1, \
  517. .r_num_mss = 2, \
  518. .is_tap = true, \
  519. }; \
  520. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_2mss) { \
  521. /* no GSO: send exactly 2 MSS */ \
  522. .tunnel_type = type, \
  523. .gso_size = UDP_TUNNEL_MSS(type), \
  524. .data_size = UDP_TUNNEL_MSS(type) * 2, \
  525. .r_num_mss = 2, \
  526. .is_tap = true, \
  527. }; \
  528. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_maxbytes) { \
  529. /* GSO: send max bytes */ \
  530. .tunnel_type = type, \
  531. .gso_size = UDP_TUNNEL_MSS(type), \
  532. .data_size = UDP_TUNNEL_MAX(type, true), \
  533. .r_num_mss = UDP_TUNNEL_MAX(type, true) / \
  534. UDP_TUNNEL_MSS(type) + 1, \
  535. .is_tap = true, \
  536. }; \
  537. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_over_maxbytes) { \
  538. /* GSO: send oversize max bytes: fail */ \
  539. .tunnel_type = type, \
  540. .gso_size = UDP_TUNNEL_MSS(type), \
  541. .data_size = ETH_MAX_MTU, \
  542. .r_num_mss = ETH_MAX_MTU / UDP_TUNNEL_MSS(type) + 1, \
  543. .is_tap = true, \
  544. }; \
  545. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_maxsegs) { \
  546. /* GSO: send max number of min sized segments */ \
  547. .tunnel_type = type, \
  548. .gso_size = 1, \
  549. .data_size = UDP_TUNNEL_MAX_SEGMENTS, \
  550. .r_num_mss = UDP_TUNNEL_MAX_SEGMENTS, \
  551. .is_tap = true, \
  552. }; \
  553. FIXTURE_VARIANT_ADD(tun_vnet_udptnl, desc##_5byte) { \
  554. /* GSO: send 5 bytes, gso 2 bytes */ \
  555. .tunnel_type = type, \
  556. .gso_size = 2, \
  557. .data_size = 5, \
  558. .r_num_mss = 3, \
  559. .is_tap = true, \
  560. } /* clang-format on */
  561. TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_4IN4, 4in4);
  562. TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_6IN4, 6in4);
  563. TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_4IN6, 4in6);
  564. TUN_VNET_UDPTNL_VARIANT_ADD(UDP_TUNNEL_GENEVE_6IN6, 6in6);
  565. static void assign_ifaddr_vars(int family, int is_outer, void **srcip,
  566. void **dstip, void **srcmac, void **dstmac)
  567. {
  568. if (is_outer) {
  569. if (family == AF_INET) {
  570. *srcip = (void *)&param_ipaddr4_outer_src;
  571. *dstip = (void *)&param_ipaddr4_outer_dst;
  572. } else {
  573. *srcip = (void *)&param_ipaddr6_outer_src;
  574. *dstip = (void *)&param_ipaddr6_outer_dst;
  575. }
  576. *srcmac = param_hwaddr_outer_src;
  577. *dstmac = param_hwaddr_outer_dst;
  578. } else {
  579. if (family == AF_INET) {
  580. *srcip = (void *)&param_ipaddr4_inner_src;
  581. *dstip = (void *)&param_ipaddr4_inner_dst;
  582. } else {
  583. *srcip = (void *)&param_ipaddr6_inner_src;
  584. *dstip = (void *)&param_ipaddr6_inner_dst;
  585. }
  586. *srcmac = param_hwaddr_inner_src;
  587. *dstmac = param_hwaddr_inner_dst;
  588. }
  589. }
  590. static void assign_sockaddr_vars(int family, int is_outer,
  591. struct sockaddr_storage *src,
  592. struct sockaddr_storage *dst)
  593. {
  594. src->ss_family = family;
  595. dst->ss_family = family;
  596. if (family == AF_INET) {
  597. struct sockaddr_in *s4 = (struct sockaddr_in *)src;
  598. struct sockaddr_in *d4 = (struct sockaddr_in *)dst;
  599. s4->sin_addr = is_outer ? param_ipaddr4_outer_src :
  600. param_ipaddr4_inner_src;
  601. d4->sin_addr = is_outer ? param_ipaddr4_outer_dst :
  602. param_ipaddr4_inner_dst;
  603. if (!is_outer) {
  604. s4->sin_port = htons(UDP_SRC_PORT);
  605. d4->sin_port = htons(UDP_DST_PORT);
  606. }
  607. } else {
  608. struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)src;
  609. struct sockaddr_in6 *d6 = (struct sockaddr_in6 *)dst;
  610. s6->sin6_addr = is_outer ? param_ipaddr6_outer_src :
  611. param_ipaddr6_inner_src;
  612. d6->sin6_addr = is_outer ? param_ipaddr6_outer_dst :
  613. param_ipaddr6_inner_dst;
  614. if (!is_outer) {
  615. s6->sin6_port = htons(UDP_SRC_PORT);
  616. d6->sin6_port = htons(UDP_DST_PORT);
  617. }
  618. }
  619. }
  620. FIXTURE_SETUP(tun_vnet_udptnl)
  621. {
  622. int ret, family, prefix, flags, features;
  623. int tunnel_type = variant->tunnel_type;
  624. struct sockaddr_storage ssa, dsa;
  625. void *sip, *dip, *smac, *dmac;
  626. flags = (variant->is_tap ? IFF_TAP : IFF_TUN) | IFF_VNET_HDR |
  627. IFF_MULTI_QUEUE | IFF_NO_PI;
  628. features = TUN_F_CSUM | TUN_F_UDP_TUNNEL_GSO |
  629. TUN_F_UDP_TUNNEL_GSO_CSUM | TUN_F_USO4 | TUN_F_USO6;
  630. self->fd = tun_open(self->ifname, flags, TUN_VNET_TNL_SIZE, features,
  631. param_hwaddr_outer_src);
  632. ASSERT_GE(self->fd, 0);
  633. family = (tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? AF_INET : AF_INET6;
  634. prefix = (family == AF_INET) ? IPPREFIX_LEN : IP6PREFIX_LEN;
  635. assign_ifaddr_vars(family, 1, &sip, &dip, &smac, &dmac);
  636. ret = ip_addr_add(self->ifname, family, sip, prefix);
  637. ASSERT_EQ(ret, 0);
  638. ret = ip_neigh_add(self->ifname, family, dip, dmac);
  639. ASSERT_EQ(ret, 0);
  640. ret = ip_route_check(self->ifname, family, sip);
  641. ASSERT_EQ(ret, 0);
  642. ret = geneve_create(param_dev_geneve_name, family, dip,
  643. param_hwaddr_inner_src);
  644. ASSERT_EQ(ret, 0);
  645. family = (tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET : AF_INET6;
  646. prefix = (family == AF_INET) ? IPPREFIX_LEN : IP6PREFIX_LEN;
  647. assign_ifaddr_vars(family, 0, &sip, &dip, &smac, &dmac);
  648. ret = ip_addr_add(param_dev_geneve_name, family, sip, prefix);
  649. ASSERT_EQ(ret, 0);
  650. ret = ip_neigh_add(param_dev_geneve_name, family, dip, dmac);
  651. ASSERT_EQ(ret, 0);
  652. ret = ip_route_check(param_dev_geneve_name, family, sip);
  653. ASSERT_EQ(ret, 0);
  654. assign_sockaddr_vars(family, 0, &ssa, &dsa);
  655. self->sock = udp_socket_open(&ssa, false, true, &dsa);
  656. ASSERT_GE(self->sock, 0);
  657. }
  658. FIXTURE_TEARDOWN(tun_vnet_udptnl)
  659. {
  660. int ret;
  661. if (self->sock != -1)
  662. close(self->sock);
  663. ret = ip_link_del(param_dev_geneve_name);
  664. EXPECT_EQ(ret, 0);
  665. ret = tun_delete(self->ifname);
  666. EXPECT_EQ(ret, 0);
  667. }
  668. static int build_gso_packet_into_tun(const FIXTURE_VARIANT(tun_vnet_udptnl) *
  669. variant,
  670. uint8_t *buf)
  671. {
  672. int pktlen, hlen, proto, inner_family, outer_family;
  673. int tunnel_type = variant->tunnel_type;
  674. int payload_len = variant->data_size;
  675. int gso_size = variant->gso_size;
  676. uint8_t *outer_udph, *cur = buf;
  677. void *sip, *dip, *smac, *dmac;
  678. bool is_tap = variant->is_tap;
  679. hlen = (is_tap ? ETH_HLEN : 0) + UDP_TUNNEL_HDRLEN(tunnel_type);
  680. inner_family = (tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET :
  681. AF_INET6;
  682. outer_family = (tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? AF_INET :
  683. AF_INET6;
  684. cur += build_virtio_net_hdr_v1_hash_tunnel(cur, is_tap, hlen, gso_size,
  685. outer_family, inner_family);
  686. pktlen = hlen + payload_len;
  687. assign_ifaddr_vars(outer_family, 1, &sip, &dip, &smac, &dmac);
  688. if (is_tap) {
  689. proto = outer_family == AF_INET ? ETH_P_IP : ETH_P_IPV6;
  690. pktlen -= ETH_HLEN;
  691. cur += build_eth(cur, proto, dmac, smac);
  692. }
  693. if (outer_family == AF_INET) {
  694. pktlen = pktlen - sizeof(struct iphdr);
  695. cur += build_ipv4_header(cur, IPPROTO_UDP, pktlen, dip, sip);
  696. } else {
  697. pktlen = pktlen - sizeof(struct ipv6hdr);
  698. cur += build_ipv6_header(cur, IPPROTO_UDP, 0, pktlen, dip, sip);
  699. }
  700. outer_udph = cur;
  701. assign_ifaddr_vars(inner_family, 0, &sip, &dip, &smac, &dmac);
  702. pktlen -= sizeof(struct udphdr);
  703. proto = inner_family == AF_INET ? ETH_P_IP : ETH_P_IPV6;
  704. cur += build_udp_header(cur, UDP_SRC_PORT, VN_PORT, pktlen);
  705. cur += build_geneve_header(cur, VN_ID);
  706. cur += build_eth(cur, proto, dmac, smac);
  707. pktlen = sizeof(struct udphdr) + payload_len;
  708. if (inner_family == AF_INET)
  709. cur += build_ipv4_header(cur, IPPROTO_UDP, pktlen, dip, sip);
  710. else
  711. cur += build_ipv6_header(cur, IPPROTO_UDP, 0, pktlen, dip, sip);
  712. cur += build_udp_packet(cur, UDP_DST_PORT, UDP_SRC_PORT, payload_len,
  713. inner_family, false);
  714. build_udp_packet_csum(outer_udph, outer_family, false);
  715. return cur - buf;
  716. }
  717. static int
  718. receive_gso_packet_from_tunnel(FIXTURE_DATA(tun_vnet_udptnl) * self,
  719. const FIXTURE_VARIANT(tun_vnet_udptnl) * variant,
  720. int *r_num_mss)
  721. {
  722. uint8_t packet_buf[MAX_VNET_TUNNEL_PACKET_SZ];
  723. int len, total_len = 0, socket = self->sock;
  724. int payload_len = variant->data_size;
  725. while (total_len < payload_len) {
  726. len = recv(socket, packet_buf, sizeof(packet_buf), 0);
  727. if (len <= 0) {
  728. if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
  729. perror("recv");
  730. break;
  731. }
  732. (*r_num_mss)++;
  733. total_len += len;
  734. }
  735. return total_len;
  736. }
  737. static int send_gso_packet_into_tunnel(FIXTURE_DATA(tun_vnet_udptnl) * self,
  738. const FIXTURE_VARIANT(tun_vnet_udptnl) *
  739. variant)
  740. {
  741. int family = (variant->tunnel_type & UDP_TUNNEL_INNER_IPV4) ? AF_INET :
  742. AF_INET6;
  743. uint8_t buf[MAX_VNET_TUNNEL_PACKET_SZ] = { 0 };
  744. int payload_len = variant->data_size;
  745. int gso_size = variant->gso_size;
  746. struct sockaddr_storage ssa, dsa;
  747. assign_sockaddr_vars(family, 0, &ssa, &dsa);
  748. return send_gso_udp_msg(self->sock, &dsa, buf, payload_len, gso_size);
  749. }
  750. static int
  751. receive_gso_packet_from_tun(FIXTURE_DATA(tun_vnet_udptnl) * self,
  752. const FIXTURE_VARIANT(tun_vnet_udptnl) * variant,
  753. struct virtio_net_hdr_v1_hash_tunnel *vnet_hdr)
  754. {
  755. struct timeval timeout = { .tv_sec = TIMEOUT_SEC };
  756. uint8_t buf[MAX_VNET_TUNNEL_PACKET_SZ];
  757. int tunnel_type = variant->tunnel_type;
  758. int payload_len = variant->data_size;
  759. bool is_tap = variant->is_tap;
  760. int ret, len, total_len = 0;
  761. int tun_fd = self->fd;
  762. fd_set fdset;
  763. while (total_len < payload_len) {
  764. FD_ZERO(&fdset);
  765. FD_SET(tun_fd, &fdset);
  766. ret = select(tun_fd + 1, &fdset, NULL, NULL, &timeout);
  767. if (ret <= 0) {
  768. perror("select");
  769. break;
  770. }
  771. if (!FD_ISSET(tun_fd, &fdset))
  772. continue;
  773. len = read(tun_fd, buf, sizeof(buf));
  774. if (len <= 0) {
  775. if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
  776. perror("read");
  777. break;
  778. }
  779. len = parse_udp_tunnel_vnet_packet(buf, len, tunnel_type,
  780. is_tap);
  781. if (len < 0)
  782. continue;
  783. if (total_len == 0)
  784. memcpy(vnet_hdr, buf, TUN_VNET_TNL_SIZE);
  785. total_len += len;
  786. }
  787. return total_len;
  788. }
  789. TEST_F(tun_vnet_udptnl, send_gso_packet)
  790. {
  791. uint8_t pkt[MAX_VNET_TUNNEL_PACKET_SZ];
  792. int r_num_mss = 0;
  793. int ret, off;
  794. memset(pkt, 0, sizeof(pkt));
  795. off = build_gso_packet_into_tun(variant, pkt);
  796. ret = write(self->fd, pkt, off);
  797. ASSERT_EQ(ret, off);
  798. ret = receive_gso_packet_from_tunnel(self, variant, &r_num_mss);
  799. EXPECT_EQ(ret, variant->data_size);
  800. EXPECT_EQ(r_num_mss, variant->r_num_mss);
  801. }
  802. TEST_F(tun_vnet_udptnl, recv_gso_packet)
  803. {
  804. struct virtio_net_hdr_v1_hash_tunnel vnet_hdr = { 0 };
  805. struct virtio_net_hdr_v1 *vh = &vnet_hdr.hash_hdr.hdr;
  806. int ret, gso_type = VIRTIO_NET_HDR_GSO_UDP_L4;
  807. ret = send_gso_packet_into_tunnel(self, variant);
  808. EXPECT_EQ(ret, variant->data_size);
  809. memset(&vnet_hdr, 0, sizeof(vnet_hdr));
  810. ret = receive_gso_packet_from_tun(self, variant, &vnet_hdr);
  811. EXPECT_EQ(ret, variant->data_size);
  812. if (!variant->no_gso) {
  813. EXPECT_EQ(vh->gso_size, variant->gso_size);
  814. gso_type |= (variant->tunnel_type & UDP_TUNNEL_OUTER_IPV4) ?
  815. (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4) :
  816. (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6);
  817. EXPECT_EQ(vh->gso_type, gso_type);
  818. }
  819. }
  820. XFAIL_ADD(tun_vnet_udptnl, 4in4_nogsosz_gtmss, recv_gso_packet);
  821. XFAIL_ADD(tun_vnet_udptnl, 6in4_nogsosz_gtmss, recv_gso_packet);
  822. XFAIL_ADD(tun_vnet_udptnl, 4in6_nogsosz_gtmss, recv_gso_packet);
  823. XFAIL_ADD(tun_vnet_udptnl, 6in6_nogsosz_gtmss, recv_gso_packet);
  824. XFAIL_ADD(tun_vnet_udptnl, 4in4_over_maxbytes, send_gso_packet);
  825. XFAIL_ADD(tun_vnet_udptnl, 6in4_over_maxbytes, send_gso_packet);
  826. XFAIL_ADD(tun_vnet_udptnl, 4in6_over_maxbytes, send_gso_packet);
  827. XFAIL_ADD(tun_vnet_udptnl, 6in6_over_maxbytes, send_gso_packet);
  828. XFAIL_ADD(tun_vnet_udptnl, 4in4_over_maxbytes, recv_gso_packet);
  829. XFAIL_ADD(tun_vnet_udptnl, 6in4_over_maxbytes, recv_gso_packet);
  830. XFAIL_ADD(tun_vnet_udptnl, 4in6_over_maxbytes, recv_gso_packet);
  831. XFAIL_ADD(tun_vnet_udptnl, 6in6_over_maxbytes, recv_gso_packet);
  832. TEST_HARNESS_MAIN