| /* |
| *------------------------------------------------------------------ |
| * Copyright (c) 2018 Cisco and/or its affiliates. |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| *------------------------------------------------------------------ |
| */ |
| |
| #ifndef _AF_XDP_H_ |
| #define _AF_XDP_H_ |
| |
| #include <vlib/log.h> |
| #include <vnet/interface.h> |
| #include <bpf/xsk.h> |
| |
| #define AF_XDP_NUM_RX_QUEUES_ALL ((u16)-1) |
| |
| #define af_xdp_log(lvl, dev, f, ...) \ |
| vlib_log(lvl, af_xdp_main.log_class, "%v: " f, (dev)->name, ##__VA_ARGS__) |
| |
| #define foreach_af_xdp_device_flags \ |
| _ (0, INITIALIZED, "initialized") \ |
| _ (1, ERROR, "error") \ |
| _ (2, ADMIN_UP, "admin-up") \ |
| _ (3, LINK_UP, "link-up") \ |
| _ (4, ZEROCOPY, "zero-copy") \ |
| _ (5, SYSCALL_LOCK, "syscall-lock") |
| |
| enum |
| { |
| #define _(a, b, c) AF_XDP_DEVICE_F_##b = (1 << a), |
| foreach_af_xdp_device_flags |
| #undef _ |
| }; |
| |
| #define af_xdp_device_error(dev, fmt, ...) \ |
| if (!(dev)->error) \ |
| { \ |
| clib_error_t *err_ = clib_error_return_unix (0, fmt, ## __VA_ARGS__); \ |
| if (!clib_atomic_bool_cmp_and_swap (&(dev)->error, 0, err_)) \ |
| clib_error_free(err_); \ |
| } |
| |
| typedef enum |
| { |
| AF_XDP_RXQ_MODE_UNKNOWN, |
| AF_XDP_RXQ_MODE_POLLING, |
| AF_XDP_RXQ_MODE_INTERRUPT, |
| } __clib_packed af_xdp_rxq_mode_t; |
| |
| typedef struct |
| { |
| CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); |
| |
| /* fields below are accessed in data-plane (hot) */ |
| |
| clib_spinlock_t syscall_lock; |
| struct xsk_ring_cons rx; |
| struct xsk_ring_prod fq; |
| int xsk_fd; |
| |
| /* fields below are accessed in control-plane only (cold) */ |
| |
| uword file_index; |
| u32 queue_index; |
| af_xdp_rxq_mode_t mode; |
| } af_xdp_rxq_t; |
| |
| typedef struct |
| { |
| CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); |
| |
| /* fields below are accessed in data-plane (hot) */ |
| |
| clib_spinlock_t lock; |
| clib_spinlock_t syscall_lock; |
| struct xsk_ring_prod tx; |
| struct xsk_ring_cons cq; |
| int xsk_fd; |
| |
| /* fields below are accessed in control-plane only (cold) */ |
| |
| u32 queue_index; |
| } af_xdp_txq_t; |
| |
| typedef struct |
| { |
| CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); |
| |
| /* fields below are accessed in data-plane (hot) */ |
| |
| af_xdp_rxq_t *rxqs; |
| af_xdp_txq_t *txqs; |
| vlib_buffer_t *buffer_template; |
| u32 per_interface_next_index; |
| u32 sw_if_index; |
| u32 hw_if_index; |
| u32 flags; |
| u8 pool; /* buffer pool index */ |
| u8 txq_num; |
| |
| /* fields below are accessed in control-plane only (cold) */ |
| |
| char *name; |
| char *linux_ifname; |
| u32 dev_instance; |
| u8 hwaddr[6]; |
| |
| u8 rxq_num; |
| |
| char *netns; |
| |
| struct xsk_umem **umem; |
| struct xsk_socket **xsk; |
| |
| struct bpf_object *bpf_obj; |
| unsigned linux_ifindex; |
| |
| /* error */ |
| clib_error_t *error; |
| } af_xdp_device_t; |
| |
| typedef struct |
| { |
| af_xdp_device_t *devices; |
| vlib_log_class_t log_class; |
| u16 msg_id_base; |
| } af_xdp_main_t; |
| |
| extern af_xdp_main_t af_xdp_main; |
| |
| typedef enum |
| { |
| AF_XDP_MODE_AUTO = 0, |
| AF_XDP_MODE_COPY = 1, |
| AF_XDP_MODE_ZERO_COPY = 2, |
| } af_xdp_mode_t; |
| |
| typedef enum |
| { |
| AF_XDP_CREATE_FLAGS_NO_SYSCALL_LOCK = 1, |
| } af_xdp_create_flag_t; |
| |
| typedef struct |
| { |
| char *linux_ifname; |
| char *name; |
| char *prog; |
| char *netns; |
| af_xdp_mode_t mode; |
| af_xdp_create_flag_t flags; |
| u32 rxq_size; |
| u32 txq_size; |
| u32 rxq_num; |
| |
| /* return */ |
| int rv; |
| u32 sw_if_index; |
| clib_error_t *error; |
| } af_xdp_create_if_args_t; |
| |
| void af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args); |
| void af_xdp_delete_if (vlib_main_t * vm, af_xdp_device_t * ad); |
| |
| void af_xdp_device_input_refill (af_xdp_device_t *ad); |
| |
| extern vlib_node_registration_t af_xdp_input_node; |
| extern vnet_device_class_t af_xdp_device_class; |
| |
| /* format.c */ |
| format_function_t format_af_xdp_device; |
| format_function_t format_af_xdp_device_name; |
| format_function_t format_af_xdp_input_trace; |
| |
| /* unformat.c */ |
| unformat_function_t unformat_af_xdp_create_if_args; |
| |
| typedef struct |
| { |
| u32 next_index; |
| u32 hw_if_index; |
| } af_xdp_input_trace_t; |
| |
| #define foreach_af_xdp_tx_func_error \ |
| _ (NO_FREE_SLOTS, "no free tx slots") \ |
| _ (SYSCALL_REQUIRED, "syscall required") \ |
| _ (SYSCALL_FAILURES, "syscall failures") |
| |
| typedef enum |
| { |
| #define _(f,s) AF_XDP_TX_ERROR_##f, |
| foreach_af_xdp_tx_func_error |
| #undef _ |
| AF_XDP_TX_N_ERROR, |
| } af_xdp_tx_func_error_t; |
| |
| #endif /* _AF_XDP_H_ */ |
| |
| /* |
| * fd.io coding-style-patch-verification: ON |
| * |
| * Local Variables: |
| * eval: (c-set-style "gnu") |
| * End: |
| */ |