vector_user.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  4. */
  5. #include <stdbool.h>
  6. #include <stdio.h>
  7. #include <unistd.h>
  8. #include <stdarg.h>
  9. #include <errno.h>
  10. #include <stddef.h>
  11. #include <string.h>
  12. #include <sys/ioctl.h>
  13. #include <net/if.h>
  14. #include <linux/if_tun.h>
  15. #include <arpa/inet.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <fcntl.h>
  19. #include <sys/socket.h>
  20. #include <sys/un.h>
  21. #include <netinet/ip.h>
  22. #include <linux/if_ether.h>
  23. #include <linux/if_packet.h>
  24. #include <sys/wait.h>
  25. #include <sys/uio.h>
  26. #include <linux/virtio_net.h>
  27. #include <netdb.h>
  28. #include <stdlib.h>
  29. #include <os.h>
  30. #include <limits.h>
  31. #include <um_malloc.h>
  32. #include "vector_user.h"
  33. #define ID_GRE 0
  34. #define ID_L2TPV3 1
  35. #define ID_BESS 2
  36. #define ID_MAX 2
  37. #define TOKEN_IFNAME "ifname"
  38. #define TOKEN_SCRIPT "ifup"
  39. #define TRANS_RAW "raw"
  40. #define TRANS_RAW_LEN strlen(TRANS_RAW)
  41. #define TRANS_FD "fd"
  42. #define TRANS_FD_LEN strlen(TRANS_FD)
  43. #define TRANS_VDE "vde"
  44. #define TRANS_VDE_LEN strlen(TRANS_VDE)
  45. #define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
  46. #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
  47. #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
  48. #define UNIX_BIND_FAIL "unix_open : could not bind socket err=%i"
  49. #define BPF_ATTACH_FAIL "Failed to attach filter size %d prog %px to %d, err %d\n"
  50. #define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n"
  51. #define MAX_UN_LEN 107
  52. static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  53. static const char *template = "tapXXXXXX";
  54. /* This is very ugly and brute force lookup, but it is done
  55. * only once at initialization so not worth doing hashes or
  56. * anything more intelligent
  57. */
  58. char *uml_vector_fetch_arg(struct arglist *ifspec, char *token)
  59. {
  60. int i;
  61. for (i = 0; i < ifspec->numargs; i++) {
  62. if (strcmp(ifspec->tokens[i], token) == 0)
  63. return ifspec->values[i];
  64. }
  65. return NULL;
  66. }
  67. struct arglist *uml_parse_vector_ifspec(char *arg)
  68. {
  69. struct arglist *result;
  70. int pos, len;
  71. bool parsing_token = true, next_starts = true;
  72. if (arg == NULL)
  73. return NULL;
  74. result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL);
  75. if (result == NULL)
  76. return NULL;
  77. result->numargs = 0;
  78. len = strlen(arg);
  79. for (pos = 0; pos < len; pos++) {
  80. if (next_starts) {
  81. if (parsing_token) {
  82. result->tokens[result->numargs] = arg + pos;
  83. } else {
  84. result->values[result->numargs] = arg + pos;
  85. result->numargs++;
  86. }
  87. next_starts = false;
  88. }
  89. if (*(arg + pos) == '=') {
  90. if (parsing_token)
  91. parsing_token = false;
  92. else
  93. goto cleanup;
  94. next_starts = true;
  95. (*(arg + pos)) = '\0';
  96. }
  97. if (*(arg + pos) == ',') {
  98. parsing_token = true;
  99. next_starts = true;
  100. (*(arg + pos)) = '\0';
  101. }
  102. }
  103. return result;
  104. cleanup:
  105. printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg);
  106. kfree(result);
  107. return NULL;
  108. }
  109. /*
  110. * Socket/FD configuration functions. These return an structure
  111. * of rx and tx descriptors to cover cases where these are not
  112. * the same (f.e. read via raw socket and write via tap).
  113. */
  114. #define PATH_NET_TUN "/dev/net/tun"
  115. static int create_tap_fd(char *iface)
  116. {
  117. struct ifreq ifr;
  118. int fd = -1;
  119. int err = -ENOMEM, offload;
  120. fd = open(PATH_NET_TUN, O_RDWR);
  121. if (fd < 0) {
  122. printk(UM_KERN_ERR "uml_tap: failed to open tun device\n");
  123. goto tap_fd_cleanup;
  124. }
  125. memset(&ifr, 0, sizeof(ifr));
  126. ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
  127. strscpy(ifr.ifr_name, iface);
  128. err = ioctl(fd, TUNSETIFF, (void *) &ifr);
  129. if (err != 0) {
  130. printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n");
  131. goto tap_fd_cleanup;
  132. }
  133. offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
  134. ioctl(fd, TUNSETOFFLOAD, offload);
  135. return fd;
  136. tap_fd_cleanup:
  137. if (fd >= 0)
  138. os_close_file(fd);
  139. return err;
  140. }
  141. static int create_raw_fd(char *iface, int flags, int proto)
  142. {
  143. struct ifreq ifr;
  144. int fd = -1;
  145. struct sockaddr_ll sock;
  146. int err = -ENOMEM;
  147. fd = socket(AF_PACKET, SOCK_RAW, flags);
  148. if (fd == -1) {
  149. err = -errno;
  150. goto raw_fd_cleanup;
  151. }
  152. memset(&ifr, 0, sizeof(ifr));
  153. strscpy(ifr.ifr_name, iface);
  154. if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
  155. err = -errno;
  156. goto raw_fd_cleanup;
  157. }
  158. sock.sll_family = AF_PACKET;
  159. sock.sll_protocol = htons(proto);
  160. sock.sll_ifindex = ifr.ifr_ifindex;
  161. if (bind(fd,
  162. (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
  163. err = -errno;
  164. goto raw_fd_cleanup;
  165. }
  166. return fd;
  167. raw_fd_cleanup:
  168. printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
  169. if (fd >= 0)
  170. os_close_file(fd);
  171. return err;
  172. }
  173. static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
  174. {
  175. int fd = -1, i;
  176. char *iface;
  177. struct vector_fds *result = NULL;
  178. bool dynamic = false;
  179. char dynamic_ifname[IFNAMSIZ];
  180. char *argv[] = {NULL, NULL, NULL, NULL};
  181. iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
  182. if (iface == NULL) {
  183. dynamic = true;
  184. iface = dynamic_ifname;
  185. srand(getpid());
  186. }
  187. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  188. if (result == NULL) {
  189. printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
  190. goto tap_cleanup;
  191. }
  192. result->rx_fd = -1;
  193. result->tx_fd = -1;
  194. result->remote_addr = NULL;
  195. result->remote_addr_size = 0;
  196. /* TAP */
  197. do {
  198. if (dynamic) {
  199. strcpy(iface, template);
  200. for (i = 0; i < strlen(iface); i++) {
  201. if (iface[i] == 'X') {
  202. iface[i] = padchar[rand() % strlen(padchar)];
  203. }
  204. }
  205. }
  206. fd = create_tap_fd(iface);
  207. if ((fd < 0) && (!dynamic)) {
  208. printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
  209. goto tap_cleanup;
  210. }
  211. result->tx_fd = fd;
  212. result->rx_fd = fd;
  213. } while (fd < 0);
  214. argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
  215. if (argv[0]) {
  216. argv[1] = iface;
  217. run_helper(NULL, NULL, argv);
  218. }
  219. return result;
  220. tap_cleanup:
  221. printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
  222. kfree(result);
  223. return NULL;
  224. }
  225. static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
  226. {
  227. char *iface;
  228. struct vector_fds *result = NULL;
  229. char *argv[] = {NULL, NULL, NULL, NULL};
  230. iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
  231. if (iface == NULL) {
  232. printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
  233. goto hybrid_cleanup;
  234. }
  235. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  236. if (result == NULL) {
  237. printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
  238. goto hybrid_cleanup;
  239. }
  240. result->rx_fd = -1;
  241. result->tx_fd = -1;
  242. result->remote_addr = NULL;
  243. result->remote_addr_size = 0;
  244. /* TAP */
  245. result->tx_fd = create_tap_fd(iface);
  246. if (result->tx_fd < 0) {
  247. printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd);
  248. goto hybrid_cleanup;
  249. }
  250. /* RAW */
  251. result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
  252. if (result->rx_fd == -1) {
  253. printk(UM_KERN_ERR
  254. "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
  255. goto hybrid_cleanup;
  256. }
  257. argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
  258. if (argv[0]) {
  259. argv[1] = iface;
  260. run_helper(NULL, NULL, argv);
  261. }
  262. return result;
  263. hybrid_cleanup:
  264. printk(UM_KERN_ERR "user_init_hybrid: init failed");
  265. kfree(result);
  266. return NULL;
  267. }
  268. static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
  269. {
  270. int fd = -1;
  271. int socktype;
  272. char *src, *dst;
  273. struct vector_fds *result = NULL;
  274. struct sockaddr_un *local_addr = NULL, *remote_addr = NULL;
  275. src = uml_vector_fetch_arg(ifspec, "src");
  276. dst = uml_vector_fetch_arg(ifspec, "dst");
  277. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  278. if (result == NULL) {
  279. printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
  280. goto unix_cleanup;
  281. }
  282. remote_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
  283. if (remote_addr == NULL) {
  284. printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
  285. goto unix_cleanup;
  286. }
  287. switch (id) {
  288. case ID_BESS:
  289. socktype = SOCK_SEQPACKET;
  290. if ((src != NULL) && (strlen(src) <= MAX_UN_LEN)) {
  291. local_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
  292. if (local_addr == NULL) {
  293. printk(UM_KERN_ERR "bess open:cannot allocate local addr");
  294. goto unix_cleanup;
  295. }
  296. local_addr->sun_family = AF_UNIX;
  297. memcpy(local_addr->sun_path, src, strlen(src) + 1);
  298. }
  299. if ((dst == NULL) || (strlen(dst) > MAX_UN_LEN))
  300. goto unix_cleanup;
  301. remote_addr->sun_family = AF_UNIX;
  302. memcpy(remote_addr->sun_path, dst, strlen(dst) + 1);
  303. break;
  304. default:
  305. printk(KERN_ERR "Unsupported unix socket type\n");
  306. return NULL;
  307. }
  308. fd = socket(AF_UNIX, socktype, 0);
  309. if (fd == -1) {
  310. printk(UM_KERN_ERR
  311. "unix open: could not open socket, error = %d",
  312. -errno
  313. );
  314. goto unix_cleanup;
  315. }
  316. if (local_addr != NULL) {
  317. if (bind(fd, (struct sockaddr *) local_addr, sizeof(struct sockaddr_un))) {
  318. printk(UM_KERN_ERR UNIX_BIND_FAIL, errno);
  319. goto unix_cleanup;
  320. }
  321. }
  322. switch (id) {
  323. case ID_BESS:
  324. if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) {
  325. printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno);
  326. goto unix_cleanup;
  327. }
  328. break;
  329. }
  330. result->rx_fd = fd;
  331. result->tx_fd = fd;
  332. result->remote_addr_size = sizeof(struct sockaddr_un);
  333. result->remote_addr = remote_addr;
  334. return result;
  335. unix_cleanup:
  336. if (fd >= 0)
  337. os_close_file(fd);
  338. kfree(remote_addr);
  339. kfree(result);
  340. return NULL;
  341. }
  342. static int strtofd(const char *nptr)
  343. {
  344. long fd;
  345. char *endptr;
  346. if (nptr == NULL)
  347. return -1;
  348. errno = 0;
  349. fd = strtol(nptr, &endptr, 10);
  350. if (nptr == endptr ||
  351. errno != 0 ||
  352. *endptr != '\0' ||
  353. fd < 0 ||
  354. fd > INT_MAX) {
  355. return -1;
  356. }
  357. return fd;
  358. }
  359. static struct vector_fds *user_init_fd_fds(struct arglist *ifspec)
  360. {
  361. int fd = -1;
  362. char *fdarg = NULL;
  363. struct vector_fds *result = NULL;
  364. fdarg = uml_vector_fetch_arg(ifspec, "fd");
  365. fd = strtofd(fdarg);
  366. if (fd == -1) {
  367. printk(UM_KERN_ERR "fd open: bad or missing fd argument");
  368. goto fd_cleanup;
  369. }
  370. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  371. if (result == NULL) {
  372. printk(UM_KERN_ERR "fd open: allocation failed");
  373. goto fd_cleanup;
  374. }
  375. result->rx_fd = fd;
  376. result->tx_fd = fd;
  377. result->remote_addr_size = 0;
  378. result->remote_addr = NULL;
  379. return result;
  380. fd_cleanup:
  381. if (fd >= 0)
  382. os_close_file(fd);
  383. kfree(result);
  384. return NULL;
  385. }
  386. /* enough char to store an int type */
  387. #define ENOUGH(type) ((CHAR_BIT * sizeof(type) - 1) / 3 + 2)
  388. #define ENOUGH_OCTAL(type) ((CHAR_BIT * sizeof(type) + 2) / 3)
  389. /* vde_plug --descr xx --port2 xx --mod2 xx --group2 xx seqpacket://NN vnl (NULL) */
  390. #define VDE_MAX_ARGC 12
  391. #define VDE_SEQPACKET_HEAD "seqpacket://"
  392. #define VDE_SEQPACKET_HEAD_LEN (sizeof(VDE_SEQPACKET_HEAD) - 1)
  393. #define VDE_DEFAULT_DESCRIPTION "UML"
  394. static struct vector_fds *user_init_vde_fds(struct arglist *ifspec)
  395. {
  396. char seqpacketvnl[VDE_SEQPACKET_HEAD_LEN + ENOUGH(int) + 1];
  397. char *argv[VDE_MAX_ARGC] = {"vde_plug"};
  398. int argc = 1;
  399. int rv;
  400. int sv[2];
  401. struct vector_fds *result = NULL;
  402. char *vnl = uml_vector_fetch_arg(ifspec,"vnl");
  403. char *descr = uml_vector_fetch_arg(ifspec,"descr");
  404. char *port = uml_vector_fetch_arg(ifspec,"port");
  405. char *mode = uml_vector_fetch_arg(ifspec,"mode");
  406. char *group = uml_vector_fetch_arg(ifspec,"group");
  407. if (descr == NULL) descr = VDE_DEFAULT_DESCRIPTION;
  408. argv[argc++] = "--descr";
  409. argv[argc++] = descr;
  410. if (port != NULL) {
  411. argv[argc++] = "--port2";
  412. argv[argc++] = port;
  413. }
  414. if (mode != NULL) {
  415. argv[argc++] = "--mod2";
  416. argv[argc++] = mode;
  417. }
  418. if (group != NULL) {
  419. argv[argc++] = "--group2";
  420. argv[argc++] = group;
  421. }
  422. argv[argc++] = seqpacketvnl;
  423. argv[argc++] = vnl;
  424. argv[argc++] = NULL;
  425. rv = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv);
  426. if (rv < 0) {
  427. printk(UM_KERN_ERR "vde: seqpacket socketpair err %d", -errno);
  428. return NULL;
  429. }
  430. rv = os_set_exec_close(sv[0]);
  431. if (rv < 0) {
  432. printk(UM_KERN_ERR "vde: seqpacket socketpair cloexec err %d", -errno);
  433. goto vde_cleanup_sv;
  434. }
  435. snprintf(seqpacketvnl, sizeof(seqpacketvnl), VDE_SEQPACKET_HEAD "%d", sv[1]);
  436. run_helper(NULL, NULL, argv);
  437. close(sv[1]);
  438. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  439. if (result == NULL) {
  440. printk(UM_KERN_ERR "fd open: allocation failed");
  441. goto vde_cleanup;
  442. }
  443. result->rx_fd = sv[0];
  444. result->tx_fd = sv[0];
  445. result->remote_addr_size = 0;
  446. result->remote_addr = NULL;
  447. return result;
  448. vde_cleanup_sv:
  449. close(sv[1]);
  450. vde_cleanup:
  451. close(sv[0]);
  452. return NULL;
  453. }
  454. static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
  455. {
  456. int rxfd = -1, txfd = -1;
  457. int err = -ENOMEM;
  458. char *iface;
  459. struct vector_fds *result = NULL;
  460. char *argv[] = {NULL, NULL, NULL, NULL};
  461. iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
  462. if (iface == NULL)
  463. goto raw_cleanup;
  464. rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
  465. if (rxfd == -1) {
  466. err = -errno;
  467. goto raw_cleanup;
  468. }
  469. txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */
  470. if (txfd == -1) {
  471. err = -errno;
  472. goto raw_cleanup;
  473. }
  474. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  475. if (result != NULL) {
  476. result->rx_fd = rxfd;
  477. result->tx_fd = txfd;
  478. result->remote_addr = NULL;
  479. result->remote_addr_size = 0;
  480. }
  481. argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
  482. if (argv[0]) {
  483. argv[1] = iface;
  484. run_helper(NULL, NULL, argv);
  485. }
  486. return result;
  487. raw_cleanup:
  488. printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
  489. kfree(result);
  490. return NULL;
  491. }
  492. bool uml_raw_enable_qdisc_bypass(int fd)
  493. {
  494. int optval = 1;
  495. if (setsockopt(fd,
  496. SOL_PACKET, PACKET_QDISC_BYPASS,
  497. &optval, sizeof(optval)) != 0) {
  498. return false;
  499. }
  500. return true;
  501. }
  502. bool uml_raw_enable_vnet_headers(int fd)
  503. {
  504. int optval = 1;
  505. if (setsockopt(fd,
  506. SOL_PACKET, PACKET_VNET_HDR,
  507. &optval, sizeof(optval)) != 0) {
  508. printk(UM_KERN_INFO VNET_HDR_FAIL, fd);
  509. return false;
  510. }
  511. return true;
  512. }
  513. bool uml_tap_enable_vnet_headers(int fd)
  514. {
  515. unsigned int features;
  516. int len = sizeof(struct virtio_net_hdr);
  517. if (ioctl(fd, TUNGETFEATURES, &features) == -1) {
  518. printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno));
  519. return false;
  520. }
  521. if ((features & IFF_VNET_HDR) == 0) {
  522. printk(UM_KERN_INFO "tapraw: No VNET HEADER support");
  523. return false;
  524. }
  525. ioctl(fd, TUNSETVNETHDRSZ, &len);
  526. return true;
  527. }
  528. static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
  529. {
  530. int err = -ENOMEM;
  531. int fd = -1, gairet;
  532. struct addrinfo srchints;
  533. struct addrinfo dsthints;
  534. bool v6, udp;
  535. char *value;
  536. char *src, *dst, *srcport, *dstport;
  537. struct addrinfo *gairesult = NULL;
  538. struct vector_fds *result = NULL;
  539. value = uml_vector_fetch_arg(ifspec, "v6");
  540. v6 = false;
  541. udp = false;
  542. if (value != NULL) {
  543. if (strtol((const char *) value, NULL, 10) > 0)
  544. v6 = true;
  545. }
  546. value = uml_vector_fetch_arg(ifspec, "udp");
  547. if (value != NULL) {
  548. if (strtol((const char *) value, NULL, 10) > 0)
  549. udp = true;
  550. }
  551. src = uml_vector_fetch_arg(ifspec, "src");
  552. dst = uml_vector_fetch_arg(ifspec, "dst");
  553. srcport = uml_vector_fetch_arg(ifspec, "srcport");
  554. dstport = uml_vector_fetch_arg(ifspec, "dstport");
  555. memset(&dsthints, 0, sizeof(dsthints));
  556. if (v6)
  557. dsthints.ai_family = AF_INET6;
  558. else
  559. dsthints.ai_family = AF_INET;
  560. switch (id) {
  561. case ID_GRE:
  562. dsthints.ai_socktype = SOCK_RAW;
  563. dsthints.ai_protocol = IPPROTO_GRE;
  564. break;
  565. case ID_L2TPV3:
  566. if (udp) {
  567. dsthints.ai_socktype = SOCK_DGRAM;
  568. dsthints.ai_protocol = 0;
  569. } else {
  570. dsthints.ai_socktype = SOCK_RAW;
  571. dsthints.ai_protocol = IPPROTO_L2TP;
  572. }
  573. break;
  574. default:
  575. printk(KERN_ERR "Unsupported socket type\n");
  576. return NULL;
  577. }
  578. memcpy(&srchints, &dsthints, sizeof(struct addrinfo));
  579. gairet = getaddrinfo(src, srcport, &dsthints, &gairesult);
  580. if ((gairet != 0) || (gairesult == NULL)) {
  581. printk(UM_KERN_ERR
  582. "socket_open : could not resolve src, error = %s",
  583. gai_strerror(gairet)
  584. );
  585. return NULL;
  586. }
  587. fd = socket(gairesult->ai_family,
  588. gairesult->ai_socktype, gairesult->ai_protocol);
  589. if (fd == -1) {
  590. printk(UM_KERN_ERR
  591. "socket_open : could not open socket, error = %d",
  592. -errno
  593. );
  594. goto cleanup;
  595. }
  596. if (bind(fd,
  597. (struct sockaddr *) gairesult->ai_addr,
  598. gairesult->ai_addrlen)) {
  599. printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno);
  600. goto cleanup;
  601. }
  602. if (gairesult != NULL)
  603. freeaddrinfo(gairesult);
  604. gairesult = NULL;
  605. gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult);
  606. if ((gairet != 0) || (gairesult == NULL)) {
  607. printk(UM_KERN_ERR
  608. "socket_open : could not resolve dst, error = %s",
  609. gai_strerror(gairet)
  610. );
  611. return NULL;
  612. }
  613. result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
  614. if (result != NULL) {
  615. result->rx_fd = fd;
  616. result->tx_fd = fd;
  617. result->remote_addr = uml_kmalloc(
  618. gairesult->ai_addrlen, UM_GFP_KERNEL);
  619. if (result->remote_addr == NULL)
  620. goto cleanup;
  621. result->remote_addr_size = gairesult->ai_addrlen;
  622. memcpy(
  623. result->remote_addr,
  624. gairesult->ai_addr,
  625. gairesult->ai_addrlen
  626. );
  627. }
  628. freeaddrinfo(gairesult);
  629. return result;
  630. cleanup:
  631. if (gairesult != NULL)
  632. freeaddrinfo(gairesult);
  633. printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err);
  634. if (fd >= 0)
  635. os_close_file(fd);
  636. if (result != NULL) {
  637. kfree(result->remote_addr);
  638. kfree(result);
  639. }
  640. return NULL;
  641. }
  642. struct vector_fds *uml_vector_user_open(
  643. int unit,
  644. struct arglist *parsed
  645. )
  646. {
  647. char *transport;
  648. if (parsed == NULL) {
  649. printk(UM_KERN_ERR "no parsed config for unit %d\n", unit);
  650. return NULL;
  651. }
  652. transport = uml_vector_fetch_arg(parsed, "transport");
  653. if (transport == NULL) {
  654. printk(UM_KERN_ERR "missing transport for unit %d\n", unit);
  655. return NULL;
  656. }
  657. if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
  658. return user_init_raw_fds(parsed);
  659. if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
  660. return user_init_hybrid_fds(parsed);
  661. if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
  662. return user_init_tap_fds(parsed);
  663. if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0)
  664. return user_init_socket_fds(parsed, ID_GRE);
  665. if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0)
  666. return user_init_socket_fds(parsed, ID_L2TPV3);
  667. if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
  668. return user_init_unix_fds(parsed, ID_BESS);
  669. if (strncmp(transport, TRANS_FD, TRANS_FD_LEN) == 0)
  670. return user_init_fd_fds(parsed);
  671. if (strncmp(transport, TRANS_VDE, TRANS_VDE_LEN) == 0)
  672. return user_init_vde_fds(parsed);
  673. return NULL;
  674. }
  675. int uml_vector_sendmsg(int fd, void *hdr, int flags)
  676. {
  677. int n;
  678. CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr, flags));
  679. if ((n < 0) && (errno == EAGAIN))
  680. return 0;
  681. if (n >= 0)
  682. return n;
  683. else
  684. return -errno;
  685. }
  686. int uml_vector_recvmsg(int fd, void *hdr, int flags)
  687. {
  688. int n;
  689. struct msghdr *msg = (struct msghdr *) hdr;
  690. CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen));
  691. if ((n < 0) && (errno == EAGAIN))
  692. return 0;
  693. if (n >= 0)
  694. return n;
  695. else
  696. return -errno;
  697. }
  698. int uml_vector_writev(int fd, void *hdr, int iovcount)
  699. {
  700. int n;
  701. CATCH_EINTR(n = writev(fd, (struct iovec *) hdr, iovcount));
  702. if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
  703. return 0;
  704. if (n >= 0)
  705. return n;
  706. else
  707. return -errno;
  708. }
  709. int uml_vector_sendmmsg(
  710. int fd,
  711. void *msgvec,
  712. unsigned int vlen,
  713. unsigned int flags)
  714. {
  715. int n;
  716. CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags));
  717. if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
  718. return 0;
  719. if (n >= 0)
  720. return n;
  721. else
  722. return -errno;
  723. }
  724. int uml_vector_recvmmsg(
  725. int fd,
  726. void *msgvec,
  727. unsigned int vlen,
  728. unsigned int flags)
  729. {
  730. int n;
  731. CATCH_EINTR(
  732. n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0));
  733. if ((n < 0) && (errno == EAGAIN))
  734. return 0;
  735. if (n >= 0)
  736. return n;
  737. else
  738. return -errno;
  739. }
  740. int uml_vector_attach_bpf(int fd, void *bpf)
  741. {
  742. struct sock_fprog *prog = bpf;
  743. int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, sizeof(struct sock_fprog));
  744. if (err < 0)
  745. printk(KERN_ERR BPF_ATTACH_FAIL, prog->len, prog->filter, fd, -errno);
  746. return err;
  747. }
  748. int uml_vector_detach_bpf(int fd, void *bpf)
  749. {
  750. struct sock_fprog *prog = bpf;
  751. int err = setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, bpf, sizeof(struct sock_fprog));
  752. if (err < 0)
  753. printk(KERN_ERR BPF_DETACH_FAIL, prog->len, prog->filter, fd, -errno);
  754. return err;
  755. }
  756. void *uml_vector_default_bpf(const void *mac)
  757. {
  758. struct sock_filter *bpf;
  759. uint32_t *mac1 = (uint32_t *)(mac + 2);
  760. uint16_t *mac2 = (uint16_t *) mac;
  761. struct sock_fprog *bpf_prog;
  762. bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
  763. if (bpf_prog) {
  764. bpf_prog->len = DEFAULT_BPF_LEN;
  765. bpf_prog->filter = NULL;
  766. } else {
  767. return NULL;
  768. }
  769. bpf = uml_kmalloc(
  770. sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL);
  771. if (bpf) {
  772. bpf_prog->filter = bpf;
  773. /* ld [8] */
  774. bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 };
  775. /* jeq #0xMAC[2-6] jt 2 jf 5*/
  776. bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)};
  777. /* ldh [6] */
  778. bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 };
  779. /* jeq #0xMAC[0-1] jt 4 jf 5 */
  780. bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)};
  781. /* ret #0 */
  782. bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 };
  783. /* ret #0x40000 */
  784. bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 };
  785. } else {
  786. kfree(bpf_prog);
  787. bpf_prog = NULL;
  788. }
  789. return bpf_prog;
  790. }
  791. /* Note - this function requires a valid mac being passed as an arg */
  792. void *uml_vector_user_bpf(char *filename)
  793. {
  794. struct sock_filter *bpf;
  795. struct sock_fprog *bpf_prog;
  796. struct stat statbuf;
  797. int res, ffd = -1;
  798. if (filename == NULL)
  799. return NULL;
  800. if (stat(filename, &statbuf) < 0) {
  801. printk(KERN_ERR "Error %d reading bpf file", -errno);
  802. return false;
  803. }
  804. bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
  805. if (bpf_prog == NULL) {
  806. printk(KERN_ERR "Failed to allocate bpf prog buffer");
  807. return NULL;
  808. }
  809. bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter);
  810. bpf_prog->filter = NULL;
  811. ffd = os_open_file(filename, of_read(OPENFLAGS()), 0);
  812. if (ffd < 0) {
  813. printk(KERN_ERR "Error %d opening bpf file", -errno);
  814. goto bpf_failed;
  815. }
  816. bpf = uml_kmalloc(statbuf.st_size, UM_GFP_KERNEL);
  817. if (bpf == NULL) {
  818. printk(KERN_ERR "Failed to allocate bpf buffer");
  819. goto bpf_failed;
  820. }
  821. bpf_prog->filter = bpf;
  822. res = os_read_file(ffd, bpf, statbuf.st_size);
  823. if (res < statbuf.st_size) {
  824. printk(KERN_ERR "Failed to read bpf program %s, error %d", filename, res);
  825. kfree(bpf);
  826. goto bpf_failed;
  827. }
  828. os_close_file(ffd);
  829. return bpf_prog;
  830. bpf_failed:
  831. if (ffd > 0)
  832. os_close_file(ffd);
  833. kfree(bpf_prog);
  834. return NULL;
  835. }