This patch set introduces generic socket tap support. This allows a
means to run BPF programs or implement other functionality in both the
send and receive path of a socket.

The socket tap uses the ULP mechanism recently introduced for kTLS.
The data operations (sendmsg, recvmsg, sendpage, and splice_recv)
are intercepted. In both directions strparser is used to break the
stream into discrete application layer messages. Each message is
then run through a BPF verdict program that indicates the message
is okay, should be dropped, or should be dropped and the connection
terminated.

The data path for socket tap for TCP is illustrated below:

  +---------------------+
  |  Application        |
  |                     |
  |  sendmsg  recvmsg   |
  +---------------------+
        |         ^
        |         |
--------|---------|---------------------
        |         |
        |    +-------------+    +--------------+    +----------------+
        |    | Socket tap  |<---| Verdict prog |<---| strparser      |
        |    | recvmsg     |    |              |    | TCP data ready |
        |    +-------------+    +--------------+    +----------------+
        |                                                   ^
        |                                                   |
        |                                               TCP receive queue
        V
  +-------------+   +-----------+   +--------------+   +---------------+
  | Socket tap  |-->| strparser |-->| Verdict prog |-->| skb_send_sock |
  | sendmsg     |   | send mode |   |              |   | locked        |
  +-------------+   +-----------+   +--------------+   +---------------+
                                                             |
                                                             V
                                                        TCP write queue

Interface:

A socket tap is enabled on socket using SO_ULP socket option with
ulp type "stap". The socket option takes ULP specific configuration
in the stap_params structure. The parameters consist of four file
descriptors for BPF programs. These are for the parser (strparser)
in the send path, the verdict program for send path, the parser
and verdict programs in the receive path.

Example configuration to set a socket tap. In this case the same 
parse and verdict programs are used on send and receive sides of the
socket.:

struct {
        struct ulp_config ulpc;
        struct stap_params sp;
} my_config;

load_bpf_file("parse_kern.o");
load_bpf_file("verdict_kern.o");

my_config.ulpc.ulp_name = "stap";
my_config.sp.bpf_send_parse_fd = prog_fd[0];
my_config.sp.bpf_send_verdict_fd = prog_fd[1];
my_config.sp.bpf_recv_parse_fd = prog_fd[0];
my_config.sp.bpf_recv_verdict_fd = prog_fd[1];

setsockopt(fd, SOL_SOCKET, SO_ULP, &my_config, sizeof(myconfig)

Future work:

  - Fill in all the expected semantics. A goal of socket tap is
    transparency with applications.
  - Performance evaluation.
  - Add a mechanism to allow an admin process to tap other users'
    sockets.
  - Add userpsace tap that can diverted applciation messages through
    userpsace. I'm thinking to connect tapped sockets to KCM to provide
    for interface.
  - Integrate with kTLS.
  - SUpport for BFP_REDIRECT. This would be useful to redirect messages
    to different sockets like in John Fasatabend's socket redirect.

Tom Herbert (2):
  bpf: Add a BPF return code to disconnect a connection
  stap: Socket tap

 include/net/stap.h        |  43 +++
 include/uapi/linux/bpf.h  |   1 +
 include/uapi/linux/stap.h |  21 ++
 net/Kconfig               |   1 +
 net/Makefile              |   1 +
 net/stap/Kconfig          |   8 +
 net/stap/Makefile         |   3 +
 net/stap/stap_main.c      | 769 ++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 847 insertions(+)
 create mode 100644 include/net/stap.h
 create mode 100644 include/uapi/linux/stap.h
 create mode 100644 net/stap/Kconfig
 create mode 100644 net/stap/Makefile
 create mode 100644 net/stap/stap_main.c

-- 
2.11.0

Reply via email to