2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
12 #include <sys/ioctl.h>
14 #include <linux/if_tun.h>
15 #include <arpa/inet.h>
16 #include <sys/types.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <net/ethernet.h>
22 #include <netinet/ip.h>
23 #include <netinet/ether.h>
24 #include <linux/if_ether.h>
25 #include <linux/if_packet.h>
26 #include <sys/socket.h>
28 #include <linux/virtio_net.h>
32 #include <um_malloc.h>
33 #include "vector_user.h"
39 #define TOKEN_IFNAME "ifname"
41 #define TRANS_RAW "raw"
42 #define TRANS_RAW_LEN strlen(TRANS_RAW)
44 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
45 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
46 #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
47 #define BPF_ATTACH_FAIL "Failed to attach filter size %d to %d, err %d\n"
49 /* This is very ugly and brute force lookup, but it is done
50 * only once at initialization so not worth doing hashes or
51 * anything more intelligent
54 char *uml_vector_fetch_arg(struct arglist
*ifspec
, char *token
)
58 for (i
= 0; i
< ifspec
->numargs
; i
++) {
59 if (strcmp(ifspec
->tokens
[i
], token
) == 0)
60 return ifspec
->values
[i
];
66 struct arglist
*uml_parse_vector_ifspec(char *arg
)
68 struct arglist
*result
;
70 bool parsing_token
= true, next_starts
= true;
74 result
= uml_kmalloc(sizeof(struct arglist
), UM_GFP_KERNEL
);
79 for (pos
= 0; pos
< len
; pos
++) {
82 result
->tokens
[result
->numargs
] = arg
+ pos
;
84 result
->values
[result
->numargs
] = arg
+ pos
;
89 if (*(arg
+ pos
) == '=') {
91 parsing_token
= false;
95 (*(arg
+ pos
)) = '\0';
97 if (*(arg
+ pos
) == ',') {
100 (*(arg
+ pos
)) = '\0';
105 printk(UM_KERN_ERR
"vector_setup - Couldn't parse '%s'\n", arg
);
111 * Socket/FD configuration functions. These return an structure
112 * of rx and tx descriptors to cover cases where these are not
113 * the same (f.e. read via raw socket and write via tap).
116 #define PATH_NET_TUN "/dev/net/tun"
118 static struct vector_fds
*user_init_tap_fds(struct arglist
*ifspec
)
122 struct sockaddr_ll sock
;
123 int err
= -ENOMEM
, offload
;
125 struct vector_fds
*result
= NULL
;
127 iface
= uml_vector_fetch_arg(ifspec
, TOKEN_IFNAME
);
129 printk(UM_KERN_ERR
"uml_tap: failed to parse interface spec\n");
133 result
= uml_kmalloc(sizeof(struct vector_fds
), UM_GFP_KERNEL
);
134 if (result
== NULL
) {
135 printk(UM_KERN_ERR
"uml_tap: failed to allocate file descriptors\n");
140 result
->remote_addr
= NULL
;
141 result
->remote_addr_size
= 0;
145 fd
= open(PATH_NET_TUN
, O_RDWR
);
147 printk(UM_KERN_ERR
"uml_tap: failed to open tun device\n");
151 memset(&ifr
, 0, sizeof(ifr
));
152 ifr
.ifr_flags
= IFF_TAP
| IFF_NO_PI
| IFF_VNET_HDR
;
153 strncpy((char *)&ifr
.ifr_name
, iface
, sizeof(ifr
.ifr_name
) - 1);
155 err
= ioctl(fd
, TUNSETIFF
, (void *) &ifr
);
157 printk(UM_KERN_ERR
"uml_tap: failed to select tap interface\n");
161 offload
= TUN_F_CSUM
| TUN_F_TSO4
| TUN_F_TSO6
;
162 ioctl(fd
, TUNSETOFFLOAD
, offload
);
166 fd
= socket(AF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
169 "uml_tap: failed to create socket: %i\n", -errno
);
173 memset(&ifr
, 0, sizeof(ifr
));
174 strncpy((char *)&ifr
.ifr_name
, iface
, sizeof(ifr
.ifr_name
) - 1);
175 if (ioctl(fd
, SIOCGIFINDEX
, (void *) &ifr
) < 0) {
177 "uml_tap: failed to set interface: %i\n", -errno
);
181 sock
.sll_family
= AF_PACKET
;
182 sock
.sll_protocol
= htons(ETH_P_ALL
);
183 sock
.sll_ifindex
= ifr
.ifr_ifindex
;
186 (struct sockaddr
*) &sock
, sizeof(struct sockaddr_ll
)) < 0) {
188 "user_init_tap: failed to bind raw pair, err %d\n",
194 printk(UM_KERN_ERR
"user_init_tap: init failed, error %d", err
);
195 if (result
!= NULL
) {
196 if (result
->rx_fd
>= 0)
197 os_close_file(result
->rx_fd
);
198 if (result
->tx_fd
>= 0)
199 os_close_file(result
->tx_fd
);
206 static struct vector_fds
*user_init_raw_fds(struct arglist
*ifspec
)
209 int rxfd
= -1, txfd
= -1;
210 struct sockaddr_ll sock
;
213 struct vector_fds
*result
= NULL
;
215 iface
= uml_vector_fetch_arg(ifspec
, TOKEN_IFNAME
);
219 rxfd
= socket(AF_PACKET
, SOCK_RAW
, ETH_P_ALL
);
224 txfd
= socket(AF_PACKET
, SOCK_RAW
, 0); /* Turn off RX on this fd */
229 memset(&ifr
, 0, sizeof(ifr
));
230 strncpy((char *)&ifr
.ifr_name
, iface
, sizeof(ifr
.ifr_name
) - 1);
231 if (ioctl(rxfd
, SIOCGIFINDEX
, (void *) &ifr
) < 0) {
236 sock
.sll_family
= AF_PACKET
;
237 sock
.sll_protocol
= htons(ETH_P_ALL
);
238 sock
.sll_ifindex
= ifr
.ifr_ifindex
;
241 (struct sockaddr
*) &sock
, sizeof(struct sockaddr_ll
)) < 0) {
246 sock
.sll_family
= AF_PACKET
;
247 sock
.sll_protocol
= htons(ETH_P_IP
);
248 sock
.sll_ifindex
= ifr
.ifr_ifindex
;
251 (struct sockaddr
*) &sock
, sizeof(struct sockaddr_ll
)) < 0) {
256 result
= uml_kmalloc(sizeof(struct vector_fds
), UM_GFP_KERNEL
);
257 if (result
!= NULL
) {
258 result
->rx_fd
= rxfd
;
259 result
->tx_fd
= txfd
;
260 result
->remote_addr
= NULL
;
261 result
->remote_addr_size
= 0;
265 printk(UM_KERN_ERR
"user_init_raw: init failed, error %d", err
);
276 bool uml_raw_enable_qdisc_bypass(int fd
)
281 SOL_PACKET
, PACKET_QDISC_BYPASS
,
282 &optval
, sizeof(optval
)) != 0) {
288 bool uml_raw_enable_vnet_headers(int fd
)
293 SOL_PACKET
, PACKET_VNET_HDR
,
294 &optval
, sizeof(optval
)) != 0) {
295 printk(UM_KERN_INFO VNET_HDR_FAIL
, fd
);
300 bool uml_tap_enable_vnet_headers(int fd
)
302 unsigned int features
;
303 int len
= sizeof(struct virtio_net_hdr
);
305 if (ioctl(fd
, TUNGETFEATURES
, &features
) == -1) {
306 printk(UM_KERN_INFO TUN_GET_F_FAIL
, strerror(errno
));
309 if ((features
& IFF_VNET_HDR
) == 0) {
310 printk(UM_KERN_INFO
"tapraw: No VNET HEADER support");
313 ioctl(fd
, TUNSETVNETHDRSZ
, &len
);
317 static struct vector_fds
*user_init_socket_fds(struct arglist
*ifspec
, int id
)
321 struct addrinfo srchints
;
322 struct addrinfo dsthints
;
325 char *src
, *dst
, *srcport
, *dstport
;
326 struct addrinfo
*gairesult
= NULL
;
327 struct vector_fds
*result
= NULL
;
330 value
= uml_vector_fetch_arg(ifspec
, "v6");
334 if (strtol((const char *) value
, NULL
, 10) > 0)
338 value
= uml_vector_fetch_arg(ifspec
, "udp");
340 if (strtol((const char *) value
, NULL
, 10) > 0)
343 src
= uml_vector_fetch_arg(ifspec
, "src");
344 dst
= uml_vector_fetch_arg(ifspec
, "dst");
345 srcport
= uml_vector_fetch_arg(ifspec
, "srcport");
346 dstport
= uml_vector_fetch_arg(ifspec
, "dstport");
348 memset(&dsthints
, 0, sizeof(dsthints
));
351 dsthints
.ai_family
= AF_INET6
;
353 dsthints
.ai_family
= AF_INET
;
357 dsthints
.ai_socktype
= SOCK_RAW
;
358 dsthints
.ai_protocol
= IPPROTO_GRE
;
362 dsthints
.ai_socktype
= SOCK_DGRAM
;
363 dsthints
.ai_protocol
= 0;
365 dsthints
.ai_socktype
= SOCK_RAW
;
366 dsthints
.ai_protocol
= IPPROTO_L2TP
;
370 printk(KERN_ERR
"Unsupported socket type\n");
373 memcpy(&srchints
, &dsthints
, sizeof(struct addrinfo
));
375 gairet
= getaddrinfo(src
, srcport
, &dsthints
, &gairesult
);
376 if ((gairet
!= 0) || (gairesult
== NULL
)) {
378 "socket_open : could not resolve src, error = %s",
383 fd
= socket(gairesult
->ai_family
,
384 gairesult
->ai_socktype
, gairesult
->ai_protocol
);
387 "socket_open : could not open socket, error = %d",
393 (struct sockaddr
*) gairesult
->ai_addr
,
394 gairesult
->ai_addrlen
)) {
395 printk(UM_KERN_ERR L2TPV3_BIND_FAIL
, errno
);
399 if (gairesult
!= NULL
)
400 freeaddrinfo(gairesult
);
404 gairet
= getaddrinfo(dst
, dstport
, &dsthints
, &gairesult
);
405 if ((gairet
!= 0) || (gairesult
== NULL
)) {
407 "socket_open : could not resolve dst, error = %s",
413 result
= uml_kmalloc(sizeof(struct vector_fds
), UM_GFP_KERNEL
);
414 if (result
!= NULL
) {
417 result
->remote_addr
= uml_kmalloc(
418 gairesult
->ai_addrlen
, UM_GFP_KERNEL
);
419 if (result
->remote_addr
== NULL
)
421 result
->remote_addr_size
= gairesult
->ai_addrlen
;
425 gairesult
->ai_addrlen
428 freeaddrinfo(gairesult
);
431 if (gairesult
!= NULL
)
432 freeaddrinfo(gairesult
);
433 printk(UM_KERN_ERR
"user_init_socket: init failed, error %d", err
);
436 if (result
!= NULL
) {
437 if (result
->remote_addr
!= NULL
)
438 kfree(result
->remote_addr
);
444 struct vector_fds
*uml_vector_user_open(
446 struct arglist
*parsed
451 if (parsed
== NULL
) {
452 printk(UM_KERN_ERR
"no parsed config for unit %d\n", unit
);
455 transport
= uml_vector_fetch_arg(parsed
, "transport");
456 if (transport
== NULL
) {
457 printk(UM_KERN_ERR
"missing transport for unit %d\n", unit
);
460 if (strncmp(transport
, TRANS_RAW
, TRANS_RAW_LEN
) == 0)
461 return user_init_raw_fds(parsed
);
462 if (strncmp(transport
, TRANS_TAP
, TRANS_TAP_LEN
) == 0)
463 return user_init_tap_fds(parsed
);
464 if (strncmp(transport
, TRANS_GRE
, TRANS_GRE_LEN
) == 0)
465 return user_init_socket_fds(parsed
, ID_GRE
);
466 if (strncmp(transport
, TRANS_L2TPV3
, TRANS_L2TPV3_LEN
) == 0)
467 return user_init_socket_fds(parsed
, ID_L2TPV3
);
472 int uml_vector_sendmsg(int fd
, void *hdr
, int flags
)
476 CATCH_EINTR(n
= sendmsg(fd
, (struct msghdr
*) hdr
, flags
));
477 if ((n
< 0) && (errno
== EAGAIN
))
485 int uml_vector_recvmsg(int fd
, void *hdr
, int flags
)
489 CATCH_EINTR(n
= recvmsg(fd
, (struct msghdr
*) hdr
, flags
));
490 if ((n
< 0) && (errno
== EAGAIN
))
498 int uml_vector_writev(int fd
, void *hdr
, int iovcount
)
502 CATCH_EINTR(n
= writev(fd
, (struct iovec
*) hdr
, iovcount
));
503 if ((n
< 0) && (errno
== EAGAIN
))
511 int uml_vector_sendmmsg(
519 CATCH_EINTR(n
= sendmmsg(fd
, (struct mmsghdr
*) msgvec
, vlen
, flags
));
520 if ((n
< 0) && (errno
== EAGAIN
))
528 int uml_vector_recvmmsg(
537 n
= recvmmsg(fd
, (struct mmsghdr
*) msgvec
, vlen
, flags
, 0));
538 if ((n
< 0) && (errno
== EAGAIN
))
545 int uml_vector_attach_bpf(int fd
, void *bpf
, int bpf_len
)
547 int err
= setsockopt(fd
, SOL_SOCKET
, SO_ATTACH_FILTER
, bpf
, bpf_len
);
550 printk(KERN_ERR BPF_ATTACH_FAIL
, bpf_len
, fd
, -errno
);
554 #define DEFAULT_BPF_LEN 6
556 void *uml_vector_default_bpf(int fd
, void *mac
)
558 struct sock_filter
*bpf
;
559 uint32_t *mac1
= (uint32_t *)(mac
+ 2);
560 uint16_t *mac2
= (uint16_t *) mac
;
561 struct sock_fprog bpf_prog
= {
567 sizeof(struct sock_filter
) * DEFAULT_BPF_LEN
, UM_GFP_KERNEL
);
569 bpf_prog
.filter
= bpf
;
571 bpf
[0] = (struct sock_filter
){ 0x20, 0, 0, 0x00000008 };
572 /* jeq #0xMAC[2-6] jt 2 jf 5*/
573 bpf
[1] = (struct sock_filter
){ 0x15, 0, 3, ntohl(*mac1
)};
575 bpf
[2] = (struct sock_filter
){ 0x28, 0, 0, 0x00000006 };
576 /* jeq #0xMAC[0-1] jt 4 jf 5 */
577 bpf
[3] = (struct sock_filter
){ 0x15, 0, 1, ntohs(*mac2
)};
579 bpf
[4] = (struct sock_filter
){ 0x6, 0, 0, 0x00000000 };
581 bpf
[5] = (struct sock_filter
){ 0x6, 0, 0, 0x00040000 };
582 if (uml_vector_attach_bpf(
583 fd
, &bpf_prog
, sizeof(struct sock_fprog
)) < 0) {