tap.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. * Copyright (c) 2009 Red Hat, Inc.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include "tap_int.h"
  27. #include <sys/ioctl.h>
  28. #include <sys/wait.h>
  29. #include <sys/socket.h>
  30. #include <net/if.h>
  31. #include "net/eth.h"
  32. #include "net/net.h"
  33. #include "clients.h"
  34. #include "monitor/monitor.h"
  35. #include "system/system.h"
  36. #include "qapi/error.h"
  37. #include "qemu/cutils.h"
  38. #include "qemu/error-report.h"
  39. #include "qemu/main-loop.h"
  40. #include "qemu/sockets.h"
  41. #include "net/tap.h"
  42. #include "net/vhost_net.h"
  43. typedef struct TAPState {
  44. NetClientState nc;
  45. int fd;
  46. char down_script[1024];
  47. char down_script_arg[128];
  48. uint8_t buf[NET_BUFSIZE];
  49. bool read_poll;
  50. bool write_poll;
  51. bool using_vnet_hdr;
  52. bool has_ufo;
  53. bool has_uso;
  54. bool enabled;
  55. VHostNetState *vhost_net;
  56. unsigned host_vnet_hdr_len;
  57. Notifier exit;
  58. } TAPState;
  59. static void launch_script(const char *setup_script, const char *ifname,
  60. int fd, Error **errp);
  61. static void tap_send(void *opaque);
  62. static void tap_writable(void *opaque);
  63. static void tap_update_fd_handler(TAPState *s)
  64. {
  65. qemu_set_fd_handler(s->fd,
  66. s->read_poll && s->enabled ? tap_send : NULL,
  67. s->write_poll && s->enabled ? tap_writable : NULL,
  68. s);
  69. }
  70. static void tap_read_poll(TAPState *s, bool enable)
  71. {
  72. s->read_poll = enable;
  73. tap_update_fd_handler(s);
  74. }
  75. static void tap_write_poll(TAPState *s, bool enable)
  76. {
  77. s->write_poll = enable;
  78. tap_update_fd_handler(s);
  79. }
  80. static void tap_writable(void *opaque)
  81. {
  82. TAPState *s = opaque;
  83. tap_write_poll(s, false);
  84. qemu_flush_queued_packets(&s->nc);
  85. }
  86. static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int iovcnt)
  87. {
  88. ssize_t len;
  89. len = RETRY_ON_EINTR(writev(s->fd, iov, iovcnt));
  90. if (len == -1 && errno == EAGAIN) {
  91. tap_write_poll(s, true);
  92. return 0;
  93. }
  94. return len;
  95. }
  96. static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
  97. int iovcnt)
  98. {
  99. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  100. const struct iovec *iovp = iov;
  101. g_autofree struct iovec *iov_copy = NULL;
  102. struct virtio_net_hdr hdr = { };
  103. if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
  104. iov_copy = g_new(struct iovec, iovcnt + 1);
  105. iov_copy[0].iov_base = &hdr;
  106. iov_copy[0].iov_len = s->host_vnet_hdr_len;
  107. memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
  108. iovp = iov_copy;
  109. iovcnt++;
  110. }
  111. return tap_write_packet(s, iovp, iovcnt);
  112. }
  113. static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
  114. {
  115. struct iovec iov = {
  116. .iov_base = (void *)buf,
  117. .iov_len = size
  118. };
  119. return tap_receive_iov(nc, &iov, 1);
  120. }
  121. #ifndef __sun__
  122. ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
  123. {
  124. return read(tapfd, buf, maxlen);
  125. }
  126. #endif
  127. static void tap_send_completed(NetClientState *nc, ssize_t len)
  128. {
  129. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  130. tap_read_poll(s, true);
  131. }
  132. static void tap_send(void *opaque)
  133. {
  134. TAPState *s = opaque;
  135. int size;
  136. int packets = 0;
  137. while (true) {
  138. uint8_t *buf = s->buf;
  139. uint8_t min_pkt[ETH_ZLEN];
  140. size_t min_pktsz = sizeof(min_pkt);
  141. size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
  142. if (size <= 0) {
  143. break;
  144. }
  145. if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
  146. buf += s->host_vnet_hdr_len;
  147. size -= s->host_vnet_hdr_len;
  148. }
  149. if (net_peer_needs_padding(&s->nc)) {
  150. if (eth_pad_short_frame(min_pkt, &min_pktsz, buf, size)) {
  151. buf = min_pkt;
  152. size = min_pktsz;
  153. }
  154. }
  155. size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
  156. if (size == 0) {
  157. tap_read_poll(s, false);
  158. break;
  159. } else if (size < 0) {
  160. break;
  161. }
  162. /*
  163. * When the host keeps receiving more packets while tap_send() is
  164. * running we can hog the BQL. Limit the number of
  165. * packets that are processed per tap_send() callback to prevent
  166. * stalling the guest.
  167. */
  168. packets++;
  169. if (packets >= 50) {
  170. break;
  171. }
  172. }
  173. }
  174. static bool tap_has_ufo(NetClientState *nc)
  175. {
  176. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  177. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  178. return s->has_ufo;
  179. }
  180. static bool tap_has_uso(NetClientState *nc)
  181. {
  182. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  183. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  184. return s->has_uso;
  185. }
  186. static bool tap_has_vnet_hdr(NetClientState *nc)
  187. {
  188. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  189. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  190. return !!s->host_vnet_hdr_len;
  191. }
  192. static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
  193. {
  194. return tap_has_vnet_hdr(nc);
  195. }
  196. static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
  197. {
  198. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  199. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  200. tap_fd_set_vnet_hdr_len(s->fd, len);
  201. s->host_vnet_hdr_len = len;
  202. s->using_vnet_hdr = true;
  203. }
  204. static int tap_set_vnet_le(NetClientState *nc, bool is_le)
  205. {
  206. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  207. return tap_fd_set_vnet_le(s->fd, is_le);
  208. }
  209. static int tap_set_vnet_be(NetClientState *nc, bool is_be)
  210. {
  211. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  212. return tap_fd_set_vnet_be(s->fd, is_be);
  213. }
  214. static void tap_set_offload(NetClientState *nc, int csum, int tso4,
  215. int tso6, int ecn, int ufo, int uso4, int uso6)
  216. {
  217. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  218. if (s->fd < 0) {
  219. return;
  220. }
  221. tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo, uso4, uso6);
  222. }
  223. static void tap_exit_notify(Notifier *notifier, void *data)
  224. {
  225. TAPState *s = container_of(notifier, TAPState, exit);
  226. Error *err = NULL;
  227. if (s->down_script[0]) {
  228. launch_script(s->down_script, s->down_script_arg, s->fd, &err);
  229. if (err) {
  230. error_report_err(err);
  231. }
  232. }
  233. }
  234. static void tap_cleanup(NetClientState *nc)
  235. {
  236. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  237. if (s->vhost_net) {
  238. vhost_net_cleanup(s->vhost_net);
  239. g_free(s->vhost_net);
  240. s->vhost_net = NULL;
  241. }
  242. qemu_purge_queued_packets(nc);
  243. tap_exit_notify(&s->exit, NULL);
  244. qemu_remove_exit_notifier(&s->exit);
  245. tap_read_poll(s, false);
  246. tap_write_poll(s, false);
  247. close(s->fd);
  248. s->fd = -1;
  249. }
  250. static void tap_poll(NetClientState *nc, bool enable)
  251. {
  252. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  253. tap_read_poll(s, enable);
  254. tap_write_poll(s, enable);
  255. }
  256. static bool tap_set_steering_ebpf(NetClientState *nc, int prog_fd)
  257. {
  258. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  259. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  260. return tap_fd_set_steering_ebpf(s->fd, prog_fd) == 0;
  261. }
  262. int tap_get_fd(NetClientState *nc)
  263. {
  264. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  265. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  266. return s->fd;
  267. }
  268. /* fd support */
  269. static NetClientInfo net_tap_info = {
  270. .type = NET_CLIENT_DRIVER_TAP,
  271. .size = sizeof(TAPState),
  272. .receive = tap_receive,
  273. .receive_iov = tap_receive_iov,
  274. .poll = tap_poll,
  275. .cleanup = tap_cleanup,
  276. .has_ufo = tap_has_ufo,
  277. .has_uso = tap_has_uso,
  278. .has_vnet_hdr = tap_has_vnet_hdr,
  279. .has_vnet_hdr_len = tap_has_vnet_hdr_len,
  280. .set_offload = tap_set_offload,
  281. .set_vnet_hdr_len = tap_set_vnet_hdr_len,
  282. .set_vnet_le = tap_set_vnet_le,
  283. .set_vnet_be = tap_set_vnet_be,
  284. .set_steering_ebpf = tap_set_steering_ebpf,
  285. };
  286. static TAPState *net_tap_fd_init(NetClientState *peer,
  287. const char *model,
  288. const char *name,
  289. int fd,
  290. int vnet_hdr)
  291. {
  292. NetClientState *nc;
  293. TAPState *s;
  294. nc = qemu_new_net_client(&net_tap_info, peer, model, name);
  295. s = DO_UPCAST(TAPState, nc, nc);
  296. s->fd = fd;
  297. s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
  298. s->using_vnet_hdr = false;
  299. s->has_ufo = tap_probe_has_ufo(s->fd);
  300. s->has_uso = tap_probe_has_uso(s->fd);
  301. s->enabled = true;
  302. tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
  303. /*
  304. * Make sure host header length is set correctly in tap:
  305. * it might have been modified by another instance of qemu.
  306. */
  307. if (vnet_hdr) {
  308. tap_fd_set_vnet_hdr_len(s->fd, s->host_vnet_hdr_len);
  309. }
  310. tap_read_poll(s, true);
  311. s->vhost_net = NULL;
  312. s->exit.notify = tap_exit_notify;
  313. qemu_add_exit_notifier(&s->exit);
  314. return s;
  315. }
  316. static void close_all_fds_after_fork(int excluded_fd)
  317. {
  318. const int skip_fd[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
  319. excluded_fd};
  320. unsigned int nskip = ARRAY_SIZE(skip_fd);
  321. /*
  322. * skip_fd must be an ordered array of distinct fds, exclude
  323. * excluded_fd if already included in the [STDIN_FILENO - STDERR_FILENO]
  324. * range
  325. */
  326. if (excluded_fd <= STDERR_FILENO) {
  327. nskip--;
  328. }
  329. qemu_close_all_open_fd(skip_fd, nskip);
  330. }
  331. static void launch_script(const char *setup_script, const char *ifname,
  332. int fd, Error **errp)
  333. {
  334. int pid, status;
  335. char *args[3];
  336. char **parg;
  337. /* try to launch network script */
  338. pid = fork();
  339. if (pid < 0) {
  340. error_setg_errno(errp, errno, "could not launch network script %s",
  341. setup_script);
  342. return;
  343. }
  344. if (pid == 0) {
  345. close_all_fds_after_fork(fd);
  346. parg = args;
  347. *parg++ = (char *)setup_script;
  348. *parg++ = (char *)ifname;
  349. *parg = NULL;
  350. execv(setup_script, args);
  351. _exit(1);
  352. } else {
  353. while (waitpid(pid, &status, 0) != pid) {
  354. /* loop */
  355. }
  356. if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
  357. return;
  358. }
  359. error_setg(errp, "network script %s failed with status %d",
  360. setup_script, status);
  361. }
  362. }
  363. static int recv_fd(int c)
  364. {
  365. int fd;
  366. uint8_t msgbuf[CMSG_SPACE(sizeof(fd))];
  367. struct msghdr msg = {
  368. .msg_control = msgbuf,
  369. .msg_controllen = sizeof(msgbuf),
  370. };
  371. struct cmsghdr *cmsg;
  372. struct iovec iov;
  373. uint8_t req[1];
  374. ssize_t len;
  375. cmsg = CMSG_FIRSTHDR(&msg);
  376. cmsg->cmsg_level = SOL_SOCKET;
  377. cmsg->cmsg_type = SCM_RIGHTS;
  378. cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
  379. msg.msg_controllen = cmsg->cmsg_len;
  380. iov.iov_base = req;
  381. iov.iov_len = sizeof(req);
  382. msg.msg_iov = &iov;
  383. msg.msg_iovlen = 1;
  384. len = recvmsg(c, &msg, 0);
  385. if (len > 0) {
  386. memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
  387. return fd;
  388. }
  389. return len;
  390. }
  391. static int net_bridge_run_helper(const char *helper, const char *bridge,
  392. Error **errp)
  393. {
  394. sigset_t oldmask, mask;
  395. g_autofree char *default_helper = NULL;
  396. int pid, status;
  397. char *args[5];
  398. char **parg;
  399. int sv[2];
  400. sigemptyset(&mask);
  401. sigaddset(&mask, SIGCHLD);
  402. sigprocmask(SIG_BLOCK, &mask, &oldmask);
  403. if (!helper) {
  404. helper = default_helper = get_relocated_path(DEFAULT_BRIDGE_HELPER);
  405. }
  406. if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
  407. error_setg_errno(errp, errno, "socketpair() failed");
  408. return -1;
  409. }
  410. /* try to launch bridge helper */
  411. pid = fork();
  412. if (pid < 0) {
  413. error_setg_errno(errp, errno, "Can't fork bridge helper");
  414. return -1;
  415. }
  416. if (pid == 0) {
  417. char *fd_buf = NULL;
  418. char *br_buf = NULL;
  419. char *helper_cmd = NULL;
  420. close_all_fds_after_fork(sv[1]);
  421. fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
  422. if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
  423. /* assume helper is a command */
  424. if (strstr(helper, "--br=") == NULL) {
  425. br_buf = g_strdup_printf("%s%s", "--br=", bridge);
  426. }
  427. helper_cmd = g_strdup_printf("%s %s %s %s", helper,
  428. "--use-vnet", fd_buf, br_buf ? br_buf : "");
  429. parg = args;
  430. *parg++ = (char *)"sh";
  431. *parg++ = (char *)"-c";
  432. *parg++ = helper_cmd;
  433. *parg++ = NULL;
  434. execv("/bin/sh", args);
  435. g_free(helper_cmd);
  436. } else {
  437. /* assume helper is just the executable path name */
  438. br_buf = g_strdup_printf("%s%s", "--br=", bridge);
  439. parg = args;
  440. *parg++ = (char *)helper;
  441. *parg++ = (char *)"--use-vnet";
  442. *parg++ = fd_buf;
  443. *parg++ = br_buf;
  444. *parg++ = NULL;
  445. execv(helper, args);
  446. }
  447. g_free(fd_buf);
  448. g_free(br_buf);
  449. _exit(1);
  450. } else {
  451. int fd;
  452. int saved_errno;
  453. close(sv[1]);
  454. fd = RETRY_ON_EINTR(recv_fd(sv[0]));
  455. saved_errno = errno;
  456. close(sv[0]);
  457. while (waitpid(pid, &status, 0) != pid) {
  458. /* loop */
  459. }
  460. sigprocmask(SIG_SETMASK, &oldmask, NULL);
  461. if (fd < 0) {
  462. error_setg_errno(errp, saved_errno,
  463. "failed to recv file descriptor");
  464. return -1;
  465. }
  466. if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
  467. error_setg(errp, "bridge helper failed");
  468. return -1;
  469. }
  470. return fd;
  471. }
  472. }
  473. int net_init_bridge(const Netdev *netdev, const char *name,
  474. NetClientState *peer, Error **errp)
  475. {
  476. const NetdevBridgeOptions *bridge;
  477. const char *helper, *br;
  478. TAPState *s;
  479. int fd, vnet_hdr;
  480. assert(netdev->type == NET_CLIENT_DRIVER_BRIDGE);
  481. bridge = &netdev->u.bridge;
  482. helper = bridge->helper;
  483. br = bridge->br ?: DEFAULT_BRIDGE_INTERFACE;
  484. fd = net_bridge_run_helper(helper, br, errp);
  485. if (fd == -1) {
  486. return -1;
  487. }
  488. if (!g_unix_set_fd_nonblocking(fd, true, NULL)) {
  489. error_setg_errno(errp, errno, "Failed to set FD nonblocking");
  490. return -1;
  491. }
  492. vnet_hdr = tap_probe_vnet_hdr(fd, errp);
  493. if (vnet_hdr < 0) {
  494. close(fd);
  495. return -1;
  496. }
  497. s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
  498. qemu_set_info_str(&s->nc, "helper=%s,br=%s", helper, br);
  499. return 0;
  500. }
  501. static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
  502. const char *setup_script, char *ifname,
  503. size_t ifname_sz, int mq_required, Error **errp)
  504. {
  505. Error *err = NULL;
  506. int fd, vnet_hdr_required;
  507. if (tap->has_vnet_hdr) {
  508. *vnet_hdr = tap->vnet_hdr;
  509. vnet_hdr_required = *vnet_hdr;
  510. } else {
  511. *vnet_hdr = 1;
  512. vnet_hdr_required = 0;
  513. }
  514. fd = RETRY_ON_EINTR(tap_open(ifname, ifname_sz, vnet_hdr, vnet_hdr_required,
  515. mq_required, errp));
  516. if (fd < 0) {
  517. return -1;
  518. }
  519. if (setup_script &&
  520. setup_script[0] != '\0' &&
  521. strcmp(setup_script, "no") != 0) {
  522. launch_script(setup_script, ifname, fd, &err);
  523. if (err) {
  524. error_propagate(errp, err);
  525. close(fd);
  526. return -1;
  527. }
  528. }
  529. return fd;
  530. }
  531. #define MAX_TAP_QUEUES 1024
  532. static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
  533. const char *model, const char *name,
  534. const char *ifname, const char *script,
  535. const char *downscript, const char *vhostfdname,
  536. int vnet_hdr, int fd, Error **errp)
  537. {
  538. Error *err = NULL;
  539. TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
  540. int vhostfd;
  541. tap_set_sndbuf(s->fd, tap, &err);
  542. if (err) {
  543. error_propagate(errp, err);
  544. goto failed;
  545. }
  546. if (tap->fd || tap->fds) {
  547. qemu_set_info_str(&s->nc, "fd=%d", fd);
  548. } else if (tap->helper) {
  549. qemu_set_info_str(&s->nc, "helper=%s", tap->helper);
  550. } else {
  551. qemu_set_info_str(&s->nc, "ifname=%s,script=%s,downscript=%s", ifname,
  552. script, downscript);
  553. if (strcmp(downscript, "no") != 0) {
  554. snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);
  555. snprintf(s->down_script_arg, sizeof(s->down_script_arg),
  556. "%s", ifname);
  557. }
  558. }
  559. if (tap->has_vhost ? tap->vhost :
  560. vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
  561. VhostNetOptions options;
  562. options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
  563. options.net_backend = &s->nc;
  564. if (tap->has_poll_us) {
  565. options.busyloop_timeout = tap->poll_us;
  566. } else {
  567. options.busyloop_timeout = 0;
  568. }
  569. if (vhostfdname) {
  570. vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, &err);
  571. if (vhostfd == -1) {
  572. error_propagate(errp, err);
  573. goto failed;
  574. }
  575. if (!g_unix_set_fd_nonblocking(vhostfd, true, NULL)) {
  576. error_setg_errno(errp, errno, "%s: Can't use file descriptor %d",
  577. name, fd);
  578. goto failed;
  579. }
  580. } else {
  581. vhostfd = open("/dev/vhost-net", O_RDWR);
  582. if (vhostfd < 0) {
  583. error_setg_errno(errp, errno,
  584. "tap: open vhost char device failed");
  585. goto failed;
  586. }
  587. if (!g_unix_set_fd_nonblocking(vhostfd, true, NULL)) {
  588. error_setg_errno(errp, errno, "Failed to set FD nonblocking");
  589. goto failed;
  590. }
  591. }
  592. options.opaque = (void *)(uintptr_t)vhostfd;
  593. options.nvqs = 2;
  594. s->vhost_net = vhost_net_init(&options);
  595. if (!s->vhost_net) {
  596. error_setg(errp,
  597. "vhost-net requested but could not be initialized");
  598. goto failed;
  599. }
  600. } else if (vhostfdname) {
  601. error_setg(errp, "vhostfd(s)= is not valid without vhost");
  602. goto failed;
  603. }
  604. return;
  605. failed:
  606. qemu_del_net_client(&s->nc);
  607. }
  608. static int get_fds(char *str, char *fds[], int max)
  609. {
  610. char *ptr = str, *this;
  611. size_t len = strlen(str);
  612. int i = 0;
  613. while (i < max && ptr < str + len) {
  614. this = strchr(ptr, ':');
  615. if (this == NULL) {
  616. fds[i] = g_strdup(ptr);
  617. } else {
  618. fds[i] = g_strndup(ptr, this - ptr);
  619. }
  620. i++;
  621. if (this == NULL) {
  622. break;
  623. } else {
  624. ptr = this + 1;
  625. }
  626. }
  627. return i;
  628. }
  629. int net_init_tap(const Netdev *netdev, const char *name,
  630. NetClientState *peer, Error **errp)
  631. {
  632. const NetdevTapOptions *tap;
  633. int fd, vnet_hdr = 0, i = 0, queues;
  634. /* for the no-fd, no-helper case */
  635. const char *script;
  636. const char *downscript;
  637. Error *err = NULL;
  638. const char *vhostfdname;
  639. char ifname[128];
  640. int ret = 0;
  641. assert(netdev->type == NET_CLIENT_DRIVER_TAP);
  642. tap = &netdev->u.tap;
  643. queues = tap->has_queues ? tap->queues : 1;
  644. vhostfdname = tap->vhostfd;
  645. script = tap->script;
  646. downscript = tap->downscript;
  647. /* QEMU hubs do not support multiqueue tap, in this case peer is set.
  648. * For -netdev, peer is always NULL. */
  649. if (peer && (tap->has_queues || tap->fds || tap->vhostfds)) {
  650. error_setg(errp, "Multiqueue tap cannot be used with hubs");
  651. return -1;
  652. }
  653. if (tap->fd) {
  654. if (tap->ifname || tap->script || tap->downscript ||
  655. tap->has_vnet_hdr || tap->helper || tap->has_queues ||
  656. tap->fds || tap->vhostfds) {
  657. error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
  658. "helper=, queues=, fds=, and vhostfds= "
  659. "are invalid with fd=");
  660. return -1;
  661. }
  662. fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
  663. if (fd == -1) {
  664. return -1;
  665. }
  666. if (!g_unix_set_fd_nonblocking(fd, true, NULL)) {
  667. error_setg_errno(errp, errno, "%s: Can't use file descriptor %d",
  668. name, fd);
  669. close(fd);
  670. return -1;
  671. }
  672. vnet_hdr = tap_probe_vnet_hdr(fd, errp);
  673. if (vnet_hdr < 0) {
  674. close(fd);
  675. return -1;
  676. }
  677. net_init_tap_one(tap, peer, "tap", name, NULL,
  678. script, downscript,
  679. vhostfdname, vnet_hdr, fd, &err);
  680. if (err) {
  681. error_propagate(errp, err);
  682. close(fd);
  683. return -1;
  684. }
  685. } else if (tap->fds) {
  686. char **fds;
  687. char **vhost_fds;
  688. int nfds = 0, nvhosts = 0;
  689. if (tap->ifname || tap->script || tap->downscript ||
  690. tap->has_vnet_hdr || tap->helper || tap->has_queues ||
  691. tap->vhostfd) {
  692. error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
  693. "helper=, queues=, and vhostfd= "
  694. "are invalid with fds=");
  695. return -1;
  696. }
  697. fds = g_new0(char *, MAX_TAP_QUEUES);
  698. vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
  699. nfds = get_fds(tap->fds, fds, MAX_TAP_QUEUES);
  700. if (tap->vhostfds) {
  701. nvhosts = get_fds(tap->vhostfds, vhost_fds, MAX_TAP_QUEUES);
  702. if (nfds != nvhosts) {
  703. error_setg(errp, "The number of fds passed does not match "
  704. "the number of vhostfds passed");
  705. ret = -1;
  706. goto free_fail;
  707. }
  708. }
  709. for (i = 0; i < nfds; i++) {
  710. fd = monitor_fd_param(monitor_cur(), fds[i], errp);
  711. if (fd == -1) {
  712. ret = -1;
  713. goto free_fail;
  714. }
  715. ret = g_unix_set_fd_nonblocking(fd, true, NULL);
  716. if (!ret) {
  717. error_setg_errno(errp, errno, "%s: Can't use file descriptor %d",
  718. name, fd);
  719. goto free_fail;
  720. }
  721. if (i == 0) {
  722. vnet_hdr = tap_probe_vnet_hdr(fd, errp);
  723. if (vnet_hdr < 0) {
  724. ret = -1;
  725. goto free_fail;
  726. }
  727. } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
  728. error_setg(errp,
  729. "vnet_hdr not consistent across given tap fds");
  730. ret = -1;
  731. goto free_fail;
  732. }
  733. net_init_tap_one(tap, peer, "tap", name, ifname,
  734. script, downscript,
  735. tap->vhostfds ? vhost_fds[i] : NULL,
  736. vnet_hdr, fd, &err);
  737. if (err) {
  738. error_propagate(errp, err);
  739. ret = -1;
  740. goto free_fail;
  741. }
  742. }
  743. free_fail:
  744. for (i = 0; i < nvhosts; i++) {
  745. g_free(vhost_fds[i]);
  746. }
  747. for (i = 0; i < nfds; i++) {
  748. g_free(fds[i]);
  749. }
  750. g_free(fds);
  751. g_free(vhost_fds);
  752. return ret;
  753. } else if (tap->helper) {
  754. if (tap->ifname || tap->script || tap->downscript ||
  755. tap->has_vnet_hdr || tap->has_queues || tap->vhostfds) {
  756. error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
  757. "queues=, and vhostfds= are invalid with helper=");
  758. return -1;
  759. }
  760. fd = net_bridge_run_helper(tap->helper,
  761. tap->br ?: DEFAULT_BRIDGE_INTERFACE,
  762. errp);
  763. if (fd == -1) {
  764. return -1;
  765. }
  766. if (!g_unix_set_fd_nonblocking(fd, true, NULL)) {
  767. error_setg_errno(errp, errno, "Failed to set FD nonblocking");
  768. return -1;
  769. }
  770. vnet_hdr = tap_probe_vnet_hdr(fd, errp);
  771. if (vnet_hdr < 0) {
  772. close(fd);
  773. return -1;
  774. }
  775. net_init_tap_one(tap, peer, "bridge", name, ifname,
  776. script, downscript, vhostfdname,
  777. vnet_hdr, fd, &err);
  778. if (err) {
  779. error_propagate(errp, err);
  780. close(fd);
  781. return -1;
  782. }
  783. } else {
  784. g_autofree char *default_script = NULL;
  785. g_autofree char *default_downscript = NULL;
  786. if (tap->vhostfds) {
  787. error_setg(errp, "vhostfds= is invalid if fds= wasn't specified");
  788. return -1;
  789. }
  790. if (!script) {
  791. script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
  792. }
  793. if (!downscript) {
  794. downscript = default_downscript =
  795. get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT);
  796. }
  797. if (tap->ifname) {
  798. pstrcpy(ifname, sizeof ifname, tap->ifname);
  799. } else {
  800. ifname[0] = '\0';
  801. }
  802. for (i = 0; i < queues; i++) {
  803. fd = net_tap_init(tap, &vnet_hdr, i >= 1 ? "no" : script,
  804. ifname, sizeof ifname, queues > 1, errp);
  805. if (fd == -1) {
  806. return -1;
  807. }
  808. if (queues > 1 && i == 0 && !tap->ifname) {
  809. if (tap_fd_get_ifname(fd, ifname)) {
  810. error_setg(errp, "Fail to get ifname");
  811. close(fd);
  812. return -1;
  813. }
  814. }
  815. net_init_tap_one(tap, peer, "tap", name, ifname,
  816. i >= 1 ? "no" : script,
  817. i >= 1 ? "no" : downscript,
  818. vhostfdname, vnet_hdr, fd, &err);
  819. if (err) {
  820. error_propagate(errp, err);
  821. close(fd);
  822. return -1;
  823. }
  824. }
  825. }
  826. return 0;
  827. }
  828. VHostNetState *tap_get_vhost_net(NetClientState *nc)
  829. {
  830. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  831. assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
  832. return s->vhost_net;
  833. }
  834. int tap_enable(NetClientState *nc)
  835. {
  836. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  837. int ret;
  838. if (s->enabled) {
  839. return 0;
  840. } else {
  841. ret = tap_fd_enable(s->fd);
  842. if (ret == 0) {
  843. s->enabled = true;
  844. tap_update_fd_handler(s);
  845. }
  846. return ret;
  847. }
  848. }
  849. int tap_disable(NetClientState *nc)
  850. {
  851. TAPState *s = DO_UPCAST(TAPState, nc, nc);
  852. int ret;
  853. if (s->enabled == 0) {
  854. return 0;
  855. } else {
  856. ret = tap_fd_disable(s->fd);
  857. if (ret == 0) {
  858. qemu_purge_queued_packets(nc);
  859. s->enabled = false;
  860. tap_update_fd_handler(s);
  861. }
  862. return ret;
  863. }
  864. }