xsk.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
  2. /*
  3. * AF_XDP user-space access library.
  4. *
  5. * Copyright (c) 2018 - 2019 Intel Corporation.
  6. * Copyright (c) 2019 Facebook
  7. *
  8. * Author(s): Magnus Karlsson <magnus.karlsson@intel.com>
  9. */
  10. #ifndef __XSK_H
  11. #define __XSK_H
  12. #include <stdio.h>
  13. #include <stdint.h>
  14. #include <stdbool.h>
  15. #include <linux/if_xdp.h>
  16. #include <bpf/libbpf.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. /* Do not access these members directly. Use the functions below. */
  21. #define DEFINE_XSK_RING(name) \
  22. struct name { \
  23. __u32 cached_prod; \
  24. __u32 cached_cons; \
  25. __u32 mask; \
  26. __u32 size; \
  27. __u32 *producer; \
  28. __u32 *consumer; \
  29. void *ring; \
  30. __u32 *flags; \
  31. }
  32. DEFINE_XSK_RING(xsk_ring_prod);
  33. DEFINE_XSK_RING(xsk_ring_cons);
  34. /* For a detailed explanation on the memory barriers associated with the
  35. * ring, please take a look at net/xdp/xsk_queue.h.
  36. */
  37. struct xsk_umem;
  38. struct xsk_socket;
  39. static inline __u64 *xsk_ring_prod__fill_addr(struct xsk_ring_prod *fill,
  40. __u32 idx)
  41. {
  42. __u64 *addrs = (__u64 *)fill->ring;
  43. return &addrs[idx & fill->mask];
  44. }
  45. static inline const __u64 *
  46. xsk_ring_cons__comp_addr(const struct xsk_ring_cons *comp, __u32 idx)
  47. {
  48. const __u64 *addrs = (const __u64 *)comp->ring;
  49. return &addrs[idx & comp->mask];
  50. }
  51. static inline struct xdp_desc *xsk_ring_prod__tx_desc(struct xsk_ring_prod *tx,
  52. __u32 idx)
  53. {
  54. struct xdp_desc *descs = (struct xdp_desc *)tx->ring;
  55. return &descs[idx & tx->mask];
  56. }
  57. static inline const struct xdp_desc *
  58. xsk_ring_cons__rx_desc(const struct xsk_ring_cons *rx, __u32 idx)
  59. {
  60. const struct xdp_desc *descs = (const struct xdp_desc *)rx->ring;
  61. return &descs[idx & rx->mask];
  62. }
  63. static inline int xsk_ring_prod__needs_wakeup(const struct xsk_ring_prod *r)
  64. {
  65. return *r->flags & XDP_RING_NEED_WAKEUP;
  66. }
  67. static inline __u32 xsk_prod_nb_free(struct xsk_ring_prod *r, __u32 nb)
  68. {
  69. __u32 free_entries = r->cached_cons - r->cached_prod;
  70. if (free_entries >= nb)
  71. return free_entries;
  72. /* Refresh the local tail pointer.
  73. * cached_cons is r->size bigger than the real consumer pointer so
  74. * that this addition can be avoided in the more frequently
  75. * executed code that computs free_entries in the beginning of
  76. * this function. Without this optimization it whould have been
  77. * free_entries = r->cached_prod - r->cached_cons + r->size.
  78. */
  79. r->cached_cons = __atomic_load_n(r->consumer, __ATOMIC_ACQUIRE);
  80. r->cached_cons += r->size;
  81. return r->cached_cons - r->cached_prod;
  82. }
  83. static inline __u32 xsk_cons_nb_avail(struct xsk_ring_cons *r, __u32 nb)
  84. {
  85. __u32 entries = r->cached_prod - r->cached_cons;
  86. if (entries == 0) {
  87. r->cached_prod = __atomic_load_n(r->producer, __ATOMIC_ACQUIRE);
  88. entries = r->cached_prod - r->cached_cons;
  89. }
  90. return (entries > nb) ? nb : entries;
  91. }
  92. static inline __u32 xsk_ring_prod__reserve(struct xsk_ring_prod *prod, __u32 nb, __u32 *idx)
  93. {
  94. if (xsk_prod_nb_free(prod, nb) < nb)
  95. return 0;
  96. *idx = prod->cached_prod;
  97. prod->cached_prod += nb;
  98. return nb;
  99. }
  100. static inline void xsk_ring_prod__submit(struct xsk_ring_prod *prod, __u32 nb)
  101. {
  102. /* Make sure everything has been written to the ring before indicating
  103. * this to the kernel by writing the producer pointer.
  104. */
  105. __atomic_store_n(prod->producer, *prod->producer + nb, __ATOMIC_RELEASE);
  106. }
  107. static inline void xsk_ring_prod__cancel(struct xsk_ring_prod *prod, __u32 nb)
  108. {
  109. prod->cached_prod -= nb;
  110. }
  111. static inline __u32 xsk_ring_cons__peek(struct xsk_ring_cons *cons, __u32 nb, __u32 *idx)
  112. {
  113. __u32 entries = xsk_cons_nb_avail(cons, nb);
  114. if (entries > 0) {
  115. *idx = cons->cached_cons;
  116. cons->cached_cons += entries;
  117. }
  118. return entries;
  119. }
  120. static inline void xsk_ring_cons__cancel(struct xsk_ring_cons *cons, __u32 nb)
  121. {
  122. cons->cached_cons -= nb;
  123. }
  124. static inline void xsk_ring_cons__release(struct xsk_ring_cons *cons, __u32 nb)
  125. {
  126. /* Make sure data has been read before indicating we are done
  127. * with the entries by updating the consumer pointer.
  128. */
  129. __atomic_store_n(cons->consumer, *cons->consumer + nb, __ATOMIC_RELEASE);
  130. }
  131. static inline void *xsk_umem__get_data(void *umem_area, __u64 addr)
  132. {
  133. return &((char *)umem_area)[addr];
  134. }
  135. static inline __u64 xsk_umem__extract_addr(__u64 addr)
  136. {
  137. return addr & XSK_UNALIGNED_BUF_ADDR_MASK;
  138. }
  139. static inline __u64 xsk_umem__extract_offset(__u64 addr)
  140. {
  141. return addr >> XSK_UNALIGNED_BUF_OFFSET_SHIFT;
  142. }
  143. static inline __u64 xsk_umem__add_offset_to_addr(__u64 addr)
  144. {
  145. return xsk_umem__extract_addr(addr) + xsk_umem__extract_offset(addr);
  146. }
  147. int xsk_umem__fd(const struct xsk_umem *umem);
  148. int xsk_socket__fd(const struct xsk_socket *xsk);
  149. #define XSK_RING_CONS__DEFAULT_NUM_DESCS 2048
  150. #define XSK_RING_PROD__DEFAULT_NUM_DESCS 2048
  151. #define XSK_UMEM__DEFAULT_FRAME_SHIFT 12 /* 4096 bytes */
  152. #define XSK_UMEM__DEFAULT_FRAME_SIZE (1 << XSK_UMEM__DEFAULT_FRAME_SHIFT)
  153. #define XSK_UMEM__DEFAULT_FRAME_HEADROOM 0
  154. #define XSK_UMEM__DEFAULT_FLAGS 0
  155. struct xsk_umem_config {
  156. __u32 fill_size;
  157. __u32 comp_size;
  158. __u32 frame_size;
  159. __u32 frame_headroom;
  160. __u32 flags;
  161. __u32 tx_metadata_len;
  162. };
  163. int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags);
  164. void xsk_detach_xdp_program(int ifindex, u32 xdp_flags);
  165. int xsk_update_xskmap(struct bpf_map *map, struct xsk_socket *xsk, u32 index);
  166. void xsk_clear_xskmap(struct bpf_map *map);
  167. bool xsk_is_in_mode(u32 ifindex, int mode);
  168. struct xsk_socket_config {
  169. __u32 rx_size;
  170. __u32 tx_size;
  171. __u16 bind_flags;
  172. };
  173. /* Set config to NULL to get the default configuration. */
  174. int xsk_umem__create(struct xsk_umem **umem,
  175. void *umem_area, __u64 size,
  176. struct xsk_ring_prod *fill,
  177. struct xsk_ring_cons *comp,
  178. const struct xsk_umem_config *config);
  179. int xsk_socket__create(struct xsk_socket **xsk,
  180. int ifindex, __u32 queue_id,
  181. struct xsk_umem *umem,
  182. struct xsk_ring_cons *rx,
  183. struct xsk_ring_prod *tx,
  184. const struct xsk_socket_config *config);
  185. int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
  186. int ifindex,
  187. __u32 queue_id, struct xsk_umem *umem,
  188. struct xsk_ring_cons *rx,
  189. struct xsk_ring_prod *tx,
  190. struct xsk_ring_prod *fill,
  191. struct xsk_ring_cons *comp,
  192. const struct xsk_socket_config *config);
  193. /* Returns 0 for success and -EBUSY if the umem is still in use. */
  194. int xsk_umem__delete(struct xsk_umem *umem);
  195. void xsk_socket__delete(struct xsk_socket *xsk);
  196. int xsk_set_mtu(int ifindex, int mtu);
  197. #ifdef __cplusplus
  198. } /* extern "C" */
  199. #endif
  200. #endif /* __XSK_H */