diff options
author | Michael Brown <mcb30@ipxe.org> | 2021-03-02 10:20:55 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2021-03-02 11:09:57 +0000 |
commit | 2b5d3f582f718ca11488fb6d92ea39dd22b8ffed (patch) | |
tree | a4ab380c613b7fa3261f7538fc8524b04b610dc0 /src/interface | |
parent | 916ebef1984e9caa05646463734b51202b405774 (diff) | |
download | ipxe-2b5d3f582f718ca11488fb6d92ea39dd22b8ffed.zip ipxe-2b5d3f582f718ca11488fb6d92ea39dd22b8ffed.tar.gz ipxe-2b5d3f582f718ca11488fb6d92ea39dd22b8ffed.tar.bz2 |
[slirp] Add libslirp driver for Linux
Add a driver using libslirp to provide a virtual network interface
without requiring root permissions on the host. This simplifies the
process of running iPXE as a Linux userspace application with network
access. For example:
make bin-x86_64-linux/slirp.linux
./bin-x86_64-linux/slirp.linux --net slirp
libslirp will provide a built-in emulated DHCP server and NAT router.
Settings such as the boot filename may be controlled via command-line
options. For example:
./bin-x86_64-linux/slirp.linux \
--net slirp,filename=http://192.168.0.1/boot.ipxe
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface')
-rw-r--r-- | src/interface/linux/linux_api.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/interface/linux/linux_api.c b/src/interface/linux/linux_api.c index 4ab3c66..1f44b53 100644 --- a/src/interface/linux/linux_api.c +++ b/src/interface/linux/linux_api.c @@ -24,6 +24,7 @@ #include <unistd.h> #include <string.h> #include <errno.h> +#include <assert.h> #include <fcntl.h> #include <time.h> #include <poll.h> @@ -31,7 +32,13 @@ #include <sys/mman.h> #include <sys/socket.h> #include <sys/time.h> +#include <netinet/in.h> #include <ipxe/linux_api.h> +#include <ipxe/slirp.h> + +#ifdef HAVE_LIBSLIRP +#include <slirp/libslirp.h> +#endif /** @file * @@ -347,6 +354,152 @@ const char * __asmcall linux_strerror ( int linux_errno ) { /****************************************************************************** * + * libslirp wrappers + * + ****************************************************************************** + */ + +#ifdef HAVE_LIBSLIRP + +/** + * Wrap slirp_new() + * + */ +struct Slirp * __asmcall +linux_slirp_new ( const struct slirp_config *config, + const struct slirp_callbacks *callbacks, void *opaque ) { + const union { + struct slirp_callbacks callbacks; + SlirpCb cb; + } *u = ( ( typeof ( u ) ) callbacks ); + SlirpConfig cfg; + Slirp *slirp; + + /* Translate configuration */ + memset ( &cfg, 0, sizeof ( cfg ) ); + cfg.version = config->version; + cfg.restricted = config->restricted; + cfg.in_enabled = config->in_enabled; + cfg.vnetwork = config->vnetwork; + cfg.vnetmask = config->vnetmask; + cfg.vhost = config->vhost; + cfg.in6_enabled = config->in6_enabled; + memcpy ( &cfg.vprefix_addr6, &config->vprefix_addr6, + sizeof ( cfg.vprefix_addr6 ) ); + cfg.vprefix_len = config->vprefix_len; + memcpy ( &cfg.vhost6, &config->vhost6, sizeof ( cfg.vhost6 ) ); + cfg.vhostname = config->vhostname; + cfg.tftp_server_name = config->tftp_server_name; + cfg.tftp_path = config->tftp_path; + cfg.bootfile = config->bootfile; + cfg.vdhcp_start = config->vdhcp_start; + cfg.vnameserver = config->vnameserver; + memcpy ( &cfg.vnameserver6, &config->vnameserver6, + sizeof ( cfg.vnameserver6 ) ); + cfg.vdnssearch = config->vdnssearch; + cfg.vdomainname = config->vdomainname; + cfg.if_mtu = config->if_mtu; + cfg.if_mru = config->if_mru; + cfg.disable_host_loopback = config->disable_host_loopback; + cfg.enable_emu = config->enable_emu; + + /* Validate callback structure */ + static_assert ( &u->cb.send_packet == &u->callbacks.send_packet ); + static_assert ( &u->cb.guest_error == &u->callbacks.guest_error ); + static_assert ( &u->cb.clock_get_ns == &u->callbacks.clock_get_ns ); + static_assert ( &u->cb.timer_new == &u->callbacks.timer_new ); + static_assert ( &u->cb.timer_free == &u->callbacks.timer_free ); + static_assert ( &u->cb.timer_mod == &u->callbacks.timer_mod ); + static_assert ( &u->cb.register_poll_fd == + &u->callbacks.register_poll_fd ); + static_assert ( &u->cb.unregister_poll_fd == + &u->callbacks.unregister_poll_fd ); + static_assert ( &u->cb.notify == &u->callbacks.notify ); + + /* Create device */ + slirp = slirp_new ( &cfg, &u->cb, opaque ); + + return slirp; +} + +/** + * Wrap slirp_cleanup() + * + */ +void __asmcall linux_slirp_cleanup ( struct Slirp *slirp ) { + + slirp_cleanup ( slirp ); +} + +/** + * Wrap slirp_input() + * + */ +void __asmcall linux_slirp_input ( struct Slirp *slirp, const uint8_t *pkt, + int pkt_len ) { + + slirp_input ( slirp, pkt, pkt_len ); +} + +/** + * Wrap slirp_pollfds_fill() + * + */ +void __asmcall +linux_slirp_pollfds_fill ( struct Slirp *slirp, uint32_t *timeout, + int ( __asmcall * add_poll ) ( int fd, int events, + void *opaque ), + void *opaque ) { + + slirp_pollfds_fill ( slirp, timeout, add_poll, opaque ); +} + +/** + * Wrap slirp_pollfds_poll() + * + */ +void __asmcall +linux_slirp_pollfds_poll ( struct Slirp *slirp, int select_error, + int ( __asmcall * get_revents ) ( int idx, + void *opaque ), + void *opaque ) { + + slirp_pollfds_poll ( slirp, select_error, get_revents, opaque ); +} + +#else /* HAVE_LIBSLIRP */ + +struct Slirp * __asmcall +linux_slirp_new ( const struct slirp_config *config, + const struct slirp_callbacks *callbacks, void *opaque ) { + return NULL; +} + +void __asmcall linux_slirp_cleanup ( struct Slirp *slirp ) { +} + +void __asmcall linux_slirp_input ( struct Slirp *slirp, const uint8_t *pkt, + int pkt_len ) { +} + +void __asmcall +linux_slirp_pollfds_fill ( struct Slirp *slirp, uint32_t *timeout, + int ( __asmcall * add_poll ) ( int fd, int events, + void *opaque ), + void *opaque ) { +} + +void __asmcall +linux_slirp_pollfds_poll ( struct Slirp *slirp, int select_error, + int ( __asmcall * get_revents ) ( int idx, + void *opaque ), + void *opaque ) { +} + +#endif /* HAVE_LIBSLIRP */ + +/****************************************************************************** + * * Symbol aliases * ****************************************************************************** @@ -371,3 +524,8 @@ PROVIDE_IPXE_SYM ( linux_socket ); PROVIDE_IPXE_SYM ( linux_bind ); PROVIDE_IPXE_SYM ( linux_sendto ); PROVIDE_IPXE_SYM ( linux_strerror ); +PROVIDE_IPXE_SYM ( linux_slirp_new ); +PROVIDE_IPXE_SYM ( linux_slirp_cleanup ); +PROVIDE_IPXE_SYM ( linux_slirp_input ); +PROVIDE_IPXE_SYM ( linux_slirp_pollfds_fill ); +PROVIDE_IPXE_SYM ( linux_slirp_pollfds_poll ); |