Line data Source code
1 : #ifndef HEADER_fd_src_net_xdp_fd_xdp_redirect_user_h 2 : #define HEADER_fd_src_net_xdp_fd_xdp_redirect_user_h 3 : 4 : /* Userspace API for controlling the fd_xdp_redirect_prog program. 5 : 6 : ### XDP program 7 : 8 : This API is specific to the fd_xdp_redirect_prog.c program. 9 : Loading other XDP programs is unsupported. In short, it is 10 : responsible for identifying and redirecting packets matching the 11 : app's listener to the app's XSKs (e.g. by IP address/UDP port). 12 : See the program's source for more info. 13 : 14 : ### XDP program installation 15 : 16 : The bpf(2) syscall allows loading a compiled eBPF program into the 17 : kernel. It is recommended to enable the eBPF JIT compiler for better 18 : performance via `echo 1 >/proc/sys/net/core/bpf_jit_enable`. 19 : Manpage: https://man7.org/linux/man-pages/man2/bpf.2.html 20 : 21 : ### Lifecycle 22 : 23 : This API allows separating the XDP program installation from the app 24 : lifecycle, reducing the privileges/capabilities required at runtime. 25 : 26 : The step-by-step lifecycle looks as follows: 27 : 28 : - fd_xdp_session_init() (privileged) 29 : - For each interface to listen on 30 : - fd_xdp_hook_iface() (privileged) 31 : - For each RX/TX queue pair of this interface 32 : - fd_xsk_new() 33 : - fd_xsk_bind() 34 : - fd_xsk_join() 35 : - For each UDP/IP destination to listen on 36 : - fd_xdp_listen_udp_port() 37 : - ... Application run ... */ 38 : 39 : /* TODO: Support NUMA-aware eBPF maps */ 40 : 41 : #include "fd_xsk.h" 42 : #include "../../util/fd_util.h" 43 : 44 : /* FD_XDP_PIN_NAME_SZ: max number of chars in an eBPF pin dir name */ 45 : #define FD_XDP_PIN_NAME_SZ (255UL) 46 : 47 : struct fd_xdp_session { 48 : int udp_dsts_map_fd; /* BPF_MAP_TYPE_HASH */ 49 : }; 50 : 51 : typedef struct fd_xdp_session fd_xdp_session_t; 52 : 53 : struct fd_xdp_link_session { 54 : int xsk_map_fd; /* BPF_MAP_TYPE_XSKMAP */ 55 : int prog_fd; /* BPF_PROG_TYPE_XDP */ 56 : int prog_link_fd; /* BPF_LINK_CREATE */ 57 : }; 58 : 59 : typedef struct fd_xdp_link_session fd_xdp_link_session_t; 60 : 61 : FD_PROTOTYPES_BEGIN 62 : 63 : /* Install API (privileged) *******************************************/ 64 : 65 : /* fd_xdp_session_init: Prepare an XDP session. Returns session on 66 : success and NULL on error. Reasons for error are logged to 67 : FD_LOG_WARNING. Requires CAP_SYS_ADMIN. */ 68 : 69 : fd_xdp_session_t * 70 : fd_xdp_session_init( fd_xdp_session_t * session ); 71 : 72 : /* fd_xdp_fini: Destroy all kernel resources installed by fd_xdp 73 : corresponding to the given app name, including any XDP programs, 74 : installations, eBPF maps, and links. Returns session on success 75 : and NULL on error. Reasons for error are logged to FD_LOG_WARNING. 76 : Requires CAP_SYS_ADMIN. */ 77 : 78 : fd_xdp_session_t * 79 : fd_xdp_session_fini( fd_xdp_session_t * session ); 80 : 81 : /* fd_xdp_hook_iface: Install the XDP redirect program to the network 82 : device with name ifname. Installation lifetime is until a 83 : matching call to fd_xdp_unhook_iface() or until the system is 84 : shut down. xdp_mode is the XDP install mode (as defined by 85 : XDP_FLAGS_{...}_MODE in <linux/if_link.h>). 86 : Returns link_session on success. On error, logs reason to warning 87 : log and returns NULL. Requires CAP_SYS_ADMIN. 88 : 89 : Valid values for xdp_mode: 90 : 91 : 0 kernel default mode 92 : XDP_FLAGS_SKB_MODE sk_buff generic mode (hardware-agnostic) 93 : XDP_FLAGS_DRV_MODE driver XDP (requires driver support) 94 : XDP_FLAGS_HW_MODE hardware-accelerated XDP 95 : (requires NIC and driver support) */ 96 : 97 : fd_xdp_link_session_t * 98 : fd_xdp_link_session_init( fd_xdp_link_session_t * link_session, 99 : fd_xdp_session_t const * session, 100 : uint if_idx, 101 : uint xdp_mode ); 102 : 103 : /* fd_xdp_unhook_iface uninstalls the XDP redirect program from the 104 : network device with name ifname. Requires CAP_SYS_ADMIN. */ 105 : 106 : void 107 : fd_xdp_link_session_fini( fd_xdp_link_session_t * session ); 108 : 109 : /* Listen API (privileged) ********************************************/ 110 : 111 : /* fd_xdp_udp_dst_key returns a key for the fd_xdp_udp_dsts eBPF 112 : map given the IPv4 dest address and UDP port number. ip4_addr is the 113 : network byte order IP address. udp_port is the host byte order UDP 114 : port. */ 115 : static inline ulong 116 : fd_xdp_udp_dst_key( uint ip4_addr, 117 0 : uint udp_port ) { 118 0 : return ( (ulong)( ip4_addr )<<16 ) | fd_ushort_bswap( (ushort)udp_port ); 119 0 : } 120 : 121 : /* fd_xdp_listen_udp_port installs a listener for protocol proto on IPv4 122 : destination addr ip4_dst_addr and UDP destination port udp_dst_ports. 123 : Installation lifetime is until a matching call to 124 : fd_xdp_release_udp_port() or until the system is shut down. 125 : On interfaces running the XDP redirect program, causes matching 126 : traffic to get redirected to active XSKs, and ceases processing of 127 : matching traffic in the Linux networking stack. Returns 0 on success 128 : or if no redirect program installation was found, and -1 on error. 129 : Reasons for error are logged to FD_LOG_WARNING. */ 130 : 131 : int 132 : fd_xdp_listen_udp_port( fd_xdp_session_t * session, 133 : uint ip4_dst_addr, 134 : ushort udp_dst_port, 135 : uint proto ); 136 : 137 : /* fd_xdp_release_udp_port uninstalls a listener that was previously 138 : installed with fd_xdp_listen_udp_port(). Restores processing of 139 : matching traffic in the Linux networking stack. Returns 0 on success 140 : or if no redirect program installation was found, and -1 on error. 141 : Reasons for error are logged to FD_LOG_WARNING. */ 142 : 143 : int 144 : fd_xdp_release_udp_port( fd_xdp_session_t * sesssion, 145 : uint ip4_dst_addr, 146 : uint udp_dst_port ); 147 : 148 : /* fd_xdp_clear_listeners uninstalls all listeners previously installed 149 : via fd_xdp_listen_udp_port(). */ 150 : 151 : int 152 : fd_xdp_clear_listeners( fd_xdp_session_t * sesssion ); 153 : 154 : /* Runtime API (unprivileged) *****************************************/ 155 : 156 : /* fd_xsk_activate installs an XSK file descriptor into the XDP redirect 157 : program's XSKMAP for the network device with name fd_xsk_ifname(xsk) 158 : at key fd_xsk_ifqueue(xsk). If another XSK is already installed at 159 : this key, it will be silently replaced. The given xsk must be a 160 : valid local join to fd_xsk_t. When packets arrive on the netdev RX 161 : queue that the XSK is bound to, and the XDP program takes action 162 : XDP_REDIRECT, causes these packets to be written to the XSK RX queue. 163 : Similarly, packets written to the XSK's TX ring get sent to the 164 : corresponding netdev TX queue. Such writes may get lost on 165 : congestion. Returns xsk on success. On error, logs reason to 166 : warning log and returns NULL. */ 167 : 168 : fd_xsk_t * 169 : fd_xsk_activate( fd_xsk_t * xsk, 170 : int xsk_map_fd ); 171 : 172 : /* fd_xsk_deactivate uninstalls an XSK file descriptor from the XDP 173 : redirect program's XSKMAP. XSK will cease to receive traffic. 174 : Returns xsk on success or if no redirect program installation was 175 : found. On error, logs reason to warning log and returns NULL. */ 176 : 177 : fd_xsk_t * 178 : fd_xsk_deactivate( fd_xsk_t * xsk, 179 : int xsk_map_fd ); 180 : 181 : FD_PROTOTYPES_END 182 : 183 : #endif /* HEADER_fd_src_net_xdp_fd_xdp_redirect_user_h */