dpdk/drivers/net/tap/tap_bpf_api.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright 2017 Mellanox Technologies, Ltd
   3 */
   4
   5#include <errno.h>
   6#include <string.h>
   7#include <unistd.h>
   8#include <sys/queue.h>
   9
  10#include <rte_malloc.h>
  11#include <rte_eth_tap.h>
  12#include <tap_flow.h>
  13#include <tap_autoconf.h>
  14#include <tap_tcmsgs.h>
  15#include <tap_bpf.h>
  16#include <tap_bpf_insns.h>
  17
  18/**
  19 * Load BPF program (section cls_q) into the kernel and return a bpf fd
  20 *
  21 * @param queue_idx
  22 *   Queue index matching packet cb
  23 *
  24 * @return
  25 *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
  26 */
  27int tap_flow_bpf_cls_q(__u32 queue_idx)
  28{
  29        cls_q_insns[1].imm = queue_idx;
  30
  31        return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
  32                (struct bpf_insn *)cls_q_insns,
  33                RTE_DIM(cls_q_insns),
  34                "Dual BSD/GPL");
  35}
  36
  37/**
  38 * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
  39 *
  40 * @param[in] key_idx
  41 *   RSS MAP key index
  42 *
  43 * @param[in] map_fd
  44 *   BPF RSS map file descriptor
  45 *
  46 * @return
  47 *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
  48 */
  49int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
  50{
  51        l3_l4_hash_insns[4].imm = key_idx;
  52        l3_l4_hash_insns[9].imm = map_fd;
  53
  54        return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
  55                (struct bpf_insn *)l3_l4_hash_insns,
  56                RTE_DIM(l3_l4_hash_insns),
  57                "Dual BSD/GPL");
  58}
  59
  60/**
  61 * Helper function to convert a pointer to unsigned 64 bits
  62 *
  63 * @param[in] ptr
  64 *   pointer to address
  65 *
  66 * @return
  67 *   64 bit unsigned long type of pointer address
  68 */
  69static inline __u64 ptr_to_u64(const void *ptr)
  70{
  71        return (__u64)(unsigned long)ptr;
  72}
  73
  74/**
  75 * Call BPF system call
  76 *
  77 * @param[in] cmd
  78 *   BPF command for program loading, map creation, map entry update, etc
  79 *
  80 * @param[in] attr
  81 *   System call attributes relevant to system call command
  82 *
  83 * @param[in] size
  84 *   size of attr parameter
  85 *
  86 * @return
  87 *   -1 if BPF system call failed, 0 otherwise
  88 */
  89static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
  90                        unsigned int size)
  91{
  92        return syscall(__NR_bpf, cmd, attr, size);
  93}
  94
  95/**
  96 * Load BPF instructions to kernel
  97 *
  98 * @param[in] type
  99 *   BPF program type: classifier or action
 100 *
 101 * @param[in] insns
 102 *   Array of BPF instructions (equivalent to BPF instructions)
 103 *
 104 * @param[in] insns_cnt
 105 *   Number of BPF instructions (size of array)
 106 *
 107 * @param[in] license
 108 *   License string that must be acknowledged by the kernel
 109 *
 110 * @return
 111 *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
 112 */
 113static int bpf_load(enum bpf_prog_type type,
 114                  const struct bpf_insn *insns,
 115                  size_t insns_cnt,
 116                  const char *license)
 117{
 118        union bpf_attr attr = {};
 119
 120        bzero(&attr, sizeof(attr));
 121        attr.prog_type = type;
 122        attr.insn_cnt = (__u32)insns_cnt;
 123        attr.insns = ptr_to_u64(insns);
 124        attr.license = ptr_to_u64(license);
 125        attr.log_buf = ptr_to_u64(NULL);
 126        attr.log_level = 0;
 127        attr.kern_version = 0;
 128
 129        return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
 130}
 131
 132/**
 133 * Create BPF map for RSS rules
 134 *
 135 * @param[in] key_size
 136 *   map RSS key size
 137 *
 138 * @param[in] value_size
 139 *   Map RSS value size
 140 *
 141 * @param[in] max_entries
 142 *   Map max number of RSS entries (limit on max RSS rules)
 143 *
 144 * @return
 145 *   -1 if BPF map couldn't be created, map fd otherwise
 146 */
 147int tap_flow_bpf_rss_map_create(unsigned int key_size,
 148                unsigned int value_size,
 149                unsigned int max_entries)
 150{
 151        union bpf_attr attr = {};
 152
 153        bzero(&attr, sizeof(attr));
 154        attr.map_type    = BPF_MAP_TYPE_HASH;
 155        attr.key_size    = key_size;
 156        attr.value_size  = value_size;
 157        attr.max_entries = max_entries;
 158
 159        return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
 160}
 161
 162/**
 163 * Update RSS entry in BPF map
 164 *
 165 * @param[in] fd
 166 *   RSS map fd
 167 *
 168 * @param[in] key
 169 *   Pointer to RSS key whose entry is updated
 170 *
 171 * @param[in] value
 172 *   Pointer to RSS new updated value
 173 *
 174 * @return
 175 *   -1 if RSS entry failed to be updated, 0 otherwise
 176 */
 177int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
 178{
 179        union bpf_attr attr = {};
 180
 181        bzero(&attr, sizeof(attr));
 182
 183        attr.map_type = BPF_MAP_TYPE_HASH;
 184        attr.map_fd = fd;
 185        attr.key = ptr_to_u64(key);
 186        attr.value = ptr_to_u64(value);
 187        attr.flags = BPF_ANY;
 188
 189        return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
 190}
 191