Socket interface

Dovetail provides a way for a companion core to implement protocols in the new out-of-band protocol family (PF_OOB), or extend existing protocol implementations with out-of-band I/O capabilities (for instance, the EVL network stack extends PF_INET/udp and PF_PACKET).

To provide a service access point to the network stack a companion core may implement, Dovetail builds on the regular socket abstraction available from the in-band kernel, extending its capabilities to enabling out-of-band I/O. In other words, there is no Dovetail-specific socket implementation, only a small set of features added to the regular socket implementation in order for a companion core to implement a protocol or even extend a pre-existing one. This set is enabled when the SOCK_OOB flag is given at socket creation by the application code. For instance, the following snippet can be used with the EVL network stack which implements the PACKET protocol family on raw sockets:

	/*
	 * Get a raw socket with out-of-band capabilities.
	 */
	int s = socket(AF_PACKET, SOCK_RAW | SOCK_OOB, 0);

A pointer to an out-of-band context descriptor is added to the INET socket data structure (i.e. struct sock). When non-NULL, the socket has an out-of-band context managed by a companion core which should populate it on attachment request from the in-band network stack. The core defines the actual C type of this structure.

Alt text

Echoing the logic in place for managing files from the out-of-band execution stage, Dovetail provides the necessary support exclusively for handling I/O requests from that stage, i.e. receiving and sending data. Creating a socket, closing it, plus all ancillary operations such as binding, connecting, shutting down connections and so on are left to the regular in-band network stack as usual (In other words, don’t expect Dovetail to provide support for e.g. creating a socket from the out-of-band stage or implementing a real-time capable binding operation, it won’t).

In order for a companion core to manage sockets with out-of-band I/O capabilities, Dovetail adds several hooks to the kernel.

Implementation hooks

__weak int sock_oob_attach(struct socket *sock);

When a socket is created with the SOCK_OOB flag, Dovetail allows the companion core to set up its own context data by calling this routine. The descriptor received is already fully constructed on the in-band side at the time of the call. sock_oob_attach() should be the place where the oob_data pointer visible in struct sock is populated.

  • sock

    The address of the BSD socket descriptor to attach to the companion core.

  • sock_oob_attach() should return zero on success, or a negative errno code.


    __weak void sock_oob_release(struct socket *sock);

    A call to sock_oob_release() happens when sock - for which a previous call to sock_oob_attach() has succeeded - is closed on the in-band side. This hook is the place where the companion core may want to synchronize with the ongoing out-of-band activity on the socket, waiting for it to finish before returning.

    When this routine is called, the BSD sock is still bound to a file, but its representation in the network layer sock->sk might already be stale. Any deallocation of resources referred to by sock->oob_data should be postponed to sock_oob_destroy().

  • sock

    The address of the BSD socket descriptor to detach from the companion core.


  • __weak void sock_oob_destroy(struct sock *sk);

    A call to sock_oob_destroy() happens when the last reference to the INET socket sk is dropped, which may happen long after sock_oob_release() is called for the associated BSD socket descriptor. This routine should deallocate the resources obtained by sock_oob_attach() for tracking this socket on the out-of-band side.

  • sock

    The address of the INET socket descriptor in the processed of being destroyed.


  • __weak int sock_oob_bind(struct sock *sk, struct sockaddr *addr, int len);

    This hook is called when the code implementing an in-band protocol family (i.e. distinct from PF_OOB) attempts to bind a socket bearing the SOCK_OOB flag to an address, allowing the companion core to extend the binding logic as it sees fit. At the moment, this call is issued by the PF_INET and PF_PACKET domains exclusively. sock_oob_bind() runs once the regular binding operation for the domain has succeeded.

  • sock

    The address of the INET socket descriptor to bind an address to.

  • This call return zero on success, otherwise a negative errno status. On error, the whole binding operation fails, including the in-band binding.


    __weak int sock_oob_shutdown(struct sock *sk, int how);

    This hook is called when the code implementing an in-band protocol family (i.e. distinct from PF_OOB) attempts to shutdown a socket bearing the SOCK_OOB flag, allowing the companion core to act upon the same event as it sees fit. At the moment, this call is issued by the PF_INET domain only. sock_oob_shutdown() runs after the regular shutdown actions for the domain has succeeded, but before the associated INET socket is released.

  • sock

    The address of the INET socket descriptor to shutdown.

  • how

    The type of shutdown process, among SHUT_RD (shut down the receive side only), SHUT_WR (shut down the send side only), or SHUT_RDWR (shut down both receive and send sides).


  • __weak int sock_oob_connect(struct sock *sk, struct sockaddr *addr, int len, int flags);

    This routine is called for a socket bearing the SOCK_OOB flag, for which the in-band network stack has successfully handled a connection request.

  • sock

    The address of the INET socket descriptor to attach to the companion core.

  • This routine should return zero on success, or a negative errno status. Any error binding the socket on the out-of-band side causes the whole connection request to fail, including the in-band connection.


    __weak long sock_oob_ioctl(struct file *file, unsigned int cmd, unsigned long arg);

    This hook should be implemented by the companion core in order to receive IOCTL requests which should be handled from the out-of-band execution stage. The receiving end is a file associated to a BSD socket.

  • file

    The address of the struct file descriptor associated to a BSD socket for which an IOCTL request is received from the out-of-band execution stage.

  • This routine should return zero on success, or a negative errno status.


    __weak long sock_inband_ioctl_redirect(struct sock *sk, unsigned int cmd, unsigned long arg);

    This hook should implement a redirector of IOCTL requests for in-band protocols (i.e. distinct from PF_OOB) for which an out-of-band extension exists. In this case, the hook implemented by the companion core interposes on the normal handling of IOCTL commands, falling back to the regular IOCTL command handler unless the companion core handled it successfully.

  • sock

    The address of the INET socket descriptor for which an IOCTL request is being redirected.

  • This routine should return zero on success, or a negated errno code. On success, the request is not passed to the regular IOCTL command handler. Otherwise, if the out-of-band protocol implementation was not able to handle the IOCTL command, it should return -ENOIOCTLCMD to the caller, so that the latter passes it on to the regular IOCTL command handler.


    Last modified: Tue, 29 Oct 2024 11:16:41 +0100