1*5c4f8d80SVincenzo Maffione /*- 2*5c4f8d80SVincenzo Maffione * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*5c4f8d80SVincenzo Maffione * 4*5c4f8d80SVincenzo Maffione * Copyright (C) 2018 Universita` di Pisa 5*5c4f8d80SVincenzo Maffione * All rights reserved. 6*5c4f8d80SVincenzo Maffione * 7*5c4f8d80SVincenzo Maffione * Redistribution and use in source and binary forms, with or without 8*5c4f8d80SVincenzo Maffione * modification, are permitted provided that the following conditions 9*5c4f8d80SVincenzo Maffione * are met: 10*5c4f8d80SVincenzo Maffione * 11*5c4f8d80SVincenzo Maffione * 1. Redistributions of source code must retain the above copyright 12*5c4f8d80SVincenzo Maffione * notice, this list of conditions and the following disclaimer. 13*5c4f8d80SVincenzo Maffione * 2. Redistributions in binary form must reproduce the above copyright 14*5c4f8d80SVincenzo Maffione * notice, this list of conditions and the following disclaimer in the 15*5c4f8d80SVincenzo Maffione * documentation and/or other materials provided with the distribution. 16*5c4f8d80SVincenzo Maffione * 17*5c4f8d80SVincenzo Maffione * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*5c4f8d80SVincenzo Maffione * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*5c4f8d80SVincenzo Maffione * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*5c4f8d80SVincenzo Maffione * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*5c4f8d80SVincenzo Maffione * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*5c4f8d80SVincenzo Maffione * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*5c4f8d80SVincenzo Maffione * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*5c4f8d80SVincenzo Maffione * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*5c4f8d80SVincenzo Maffione * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*5c4f8d80SVincenzo Maffione * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*5c4f8d80SVincenzo Maffione * SUCH DAMAGE. 28*5c4f8d80SVincenzo Maffione * $FreeBSD$ 29*5c4f8d80SVincenzo Maffione */ 30*5c4f8d80SVincenzo Maffione 31*5c4f8d80SVincenzo Maffione #ifndef LIBNETMAP_H_ 32*5c4f8d80SVincenzo Maffione #define LIBNETMAP_H_ 33*5c4f8d80SVincenzo Maffione /* if thread-safety is not needed, define LIBNETMAP_NOTHREADSAFE before including 34*5c4f8d80SVincenzo Maffione * this file. 35*5c4f8d80SVincenzo Maffione */ 36*5c4f8d80SVincenzo Maffione 37*5c4f8d80SVincenzo Maffione /* NOTE: we include net/netmap_user.h without defining NETMAP_WITH_LIBS, which 38*5c4f8d80SVincenzo Maffione * is deprecated. If you still need it, please define NETMAP_WITH_LIBS and 39*5c4f8d80SVincenzo Maffione * include net/netmap_user.h before including this file. 40*5c4f8d80SVincenzo Maffione */ 41*5c4f8d80SVincenzo Maffione #include <net/netmap_user.h> 42*5c4f8d80SVincenzo Maffione 43*5c4f8d80SVincenzo Maffione struct nmctx; 44*5c4f8d80SVincenzo Maffione struct nmport_d; 45*5c4f8d80SVincenzo Maffione struct nmem_d; 46*5c4f8d80SVincenzo Maffione 47*5c4f8d80SVincenzo Maffione /* 48*5c4f8d80SVincenzo Maffione * A port open specification (portspec for brevity) has the following syntax 49*5c4f8d80SVincenzo Maffione * (square brackets delimit optional parts): 50*5c4f8d80SVincenzo Maffione * 51*5c4f8d80SVincenzo Maffione * subsystem:vpname[mode][options] 52*5c4f8d80SVincenzo Maffione * 53*5c4f8d80SVincenzo Maffione * The "subsystem" is denoted by a prefix, possibly followed by an identifier. 54*5c4f8d80SVincenzo Maffione * There can be several kinds of subsystems, each one selected by a unique 55*5c4f8d80SVincenzo Maffione * prefix. Currently defined subsystems are: 56*5c4f8d80SVincenzo Maffione * 57*5c4f8d80SVincenzo Maffione * netmap (no id allowed) 58*5c4f8d80SVincenzo Maffione * the standard subsystem 59*5c4f8d80SVincenzo Maffione * 60*5c4f8d80SVincenzo Maffione * vale (followed by a possibly empty id) 61*5c4f8d80SVincenzo Maffione * the vpname is connected to a VALE switch identified by 62*5c4f8d80SVincenzo Maffione * the id (an empty id selects the default switch) 63*5c4f8d80SVincenzo Maffione * 64*5c4f8d80SVincenzo Maffione * The "vpname" has the following syntax: 65*5c4f8d80SVincenzo Maffione * 66*5c4f8d80SVincenzo Maffione * identifier or 67*5c4f8d80SVincenzo Maffione * identifier1{identifier2 or 68*5c4f8d80SVincenzo Maffione * identifier1}identifier2 69*5c4f8d80SVincenzo Maffione * 70*5c4f8d80SVincenzo Maffione * Identifiers are sequences of alphanumeric characters. The part that begins 71*5c4f8d80SVincenzo Maffione * with either '{' or '}', when present, denotes a netmap pipe opened in the 72*5c4f8d80SVincenzo Maffione * same memory region as the subsystem:indentifier1 port. 73*5c4f8d80SVincenzo Maffione * 74*5c4f8d80SVincenzo Maffione * The "mode" can be one of the following: 75*5c4f8d80SVincenzo Maffione * 76*5c4f8d80SVincenzo Maffione * ^ bind all host (sw) ring pairs 77*5c4f8d80SVincenzo Maffione * ^NN bind individual host ring pair 78*5c4f8d80SVincenzo Maffione * * bind host and NIC ring pairs 79*5c4f8d80SVincenzo Maffione * -NN bind individual NIC ring pair 80*5c4f8d80SVincenzo Maffione * @NN open the port in the NN memory region 81*5c4f8d80SVincenzo Maffione * a suffix starting with / and the following flags, 82*5c4f8d80SVincenzo Maffione * in any order: 83*5c4f8d80SVincenzo Maffione * x exclusive access 84*5c4f8d80SVincenzo Maffione * z zero copy monitor (both tx and rx) 85*5c4f8d80SVincenzo Maffione * t monitor tx side (copy monitor) 86*5c4f8d80SVincenzo Maffione * r monitor rx side (copy monitor) 87*5c4f8d80SVincenzo Maffione * R bind only RX ring(s) 88*5c4f8d80SVincenzo Maffione * T bind only TX ring(s) 89*5c4f8d80SVincenzo Maffione * 90*5c4f8d80SVincenzo Maffione * The "options" start at the first '@' character not followed by a number. 91*5c4f8d80SVincenzo Maffione * Each option starts with '@' and has the following syntax: 92*5c4f8d80SVincenzo Maffione * 93*5c4f8d80SVincenzo Maffione * option (flag option) 94*5c4f8d80SVincenzo Maffione * option=value (single key option) 95*5c4f8d80SVincenzo Maffione * option:key1=value1,key2=value2,... (multi-key option) 96*5c4f8d80SVincenzo Maffione * 97*5c4f8d80SVincenzo Maffione * For multi-key options, the keys can be assigned in any order, but they 98*5c4f8d80SVincenzo Maffione * cannot be assigned more than once. It is not necessary to assign all the 99*5c4f8d80SVincenzo Maffione * option keys: unmentioned keys will receive default values. Some multi-key 100*5c4f8d80SVincenzo Maffione * options define a default key and also accept the single-key syntax, by 101*5c4f8d80SVincenzo Maffione * assigning the value to this key. 102*5c4f8d80SVincenzo Maffione * 103*5c4f8d80SVincenzo Maffione * NOTE: Options may be silently ignored if the port is already open by some 104*5c4f8d80SVincenzo Maffione * other process. 105*5c4f8d80SVincenzo Maffione * 106*5c4f8d80SVincenzo Maffione * The currently available options are (default keys, when defined, are marked 107*5c4f8d80SVincenzo Maffione * with '*'): 108*5c4f8d80SVincenzo Maffione * 109*5c4f8d80SVincenzo Maffione * share (single-key) 110*5c4f8d80SVincenzo Maffione * open the port in the same memory region used by the 111*5c4f8d80SVincenzo Maffione * given port name (the port name must be given in 112*5c4f8d80SVincenzo Maffione * subsystem:vpname form) 113*5c4f8d80SVincenzo Maffione * 114*5c4f8d80SVincenzo Maffione * conf (multi-key) 115*5c4f8d80SVincenzo Maffione * specify the rings/slots numbers (effective only on 116*5c4f8d80SVincenzo Maffione * ports that are created by the open operation itself, 117*5c4f8d80SVincenzo Maffione * and ignored otherwise). 118*5c4f8d80SVincenzo Maffione * 119*5c4f8d80SVincenzo Maffione * The keys are: 120*5c4f8d80SVincenzo Maffione * 121*5c4f8d80SVincenzo Maffione * *rings number of tx and rx rings 122*5c4f8d80SVincenzo Maffione * tx-rings number of tx rings 123*5c4f8d80SVincenzo Maffione * rx-rings number of rx rings 124*5c4f8d80SVincenzo Maffione * host-rings number of tx and rx host rings 125*5c4f8d80SVincenzo Maffione * host-tx-rings number of host tx rings 126*5c4f8d80SVincenzo Maffione * host-rx-rings number of host rx rings 127*5c4f8d80SVincenzo Maffione * slots number of slots in each tx and rx 128*5c4f8d80SVincenzo Maffione * ring 129*5c4f8d80SVincenzo Maffione * tx-slots number of slots in each tx ring 130*5c4f8d80SVincenzo Maffione * rx-slots number of slots in each rx ring 131*5c4f8d80SVincenzo Maffione * 132*5c4f8d80SVincenzo Maffione * (more specific keys override the less specific ones) 133*5c4f8d80SVincenzo Maffione * All keys default to zero if not assigned, and the 134*5c4f8d80SVincenzo Maffione * corresponding value will be chosen by netmap. 135*5c4f8d80SVincenzo Maffione * 136*5c4f8d80SVincenzo Maffione * extmem (multi-key) 137*5c4f8d80SVincenzo Maffione * open the port in the memory region obtained by 138*5c4f8d80SVincenzo Maffione * mmap()ing the given file. 139*5c4f8d80SVincenzo Maffione * 140*5c4f8d80SVincenzo Maffione * The keys are: 141*5c4f8d80SVincenzo Maffione * 142*5c4f8d80SVincenzo Maffione * *file the file to mmap 143*5c4f8d80SVincenzo Maffione * if-num number of pre-allocated netmap_if's 144*5c4f8d80SVincenzo Maffione * if-size size of each netmap_if 145*5c4f8d80SVincenzo Maffione * ring-num number of pre-allocated netmap_ring's 146*5c4f8d80SVincenzo Maffione * ring-size size of each netmap_ring 147*5c4f8d80SVincenzo Maffione * buf-num number of pre-allocated buffers 148*5c4f8d80SVincenzo Maffione * buf-size size of each buffer 149*5c4f8d80SVincenzo Maffione * 150*5c4f8d80SVincenzo Maffione * file must be assigned. The other keys default to zero, 151*5c4f8d80SVincenzo Maffione * causing netmap to take the corresponding values from 152*5c4f8d80SVincenzo Maffione * the priv_{if,ring,buf}_{num,size} sysctls. 153*5c4f8d80SVincenzo Maffione * 154*5c4f8d80SVincenzo Maffione */ 155*5c4f8d80SVincenzo Maffione 156*5c4f8d80SVincenzo Maffione 157*5c4f8d80SVincenzo Maffione /* nmport manipulation */ 158*5c4f8d80SVincenzo Maffione 159*5c4f8d80SVincenzo Maffione /* struct nmport_d - describes a netmap port */ 160*5c4f8d80SVincenzo Maffione struct nmport_d { 161*5c4f8d80SVincenzo Maffione /* see net/netmap.h for the definition of these fields */ 162*5c4f8d80SVincenzo Maffione struct nmreq_header hdr; 163*5c4f8d80SVincenzo Maffione struct nmreq_register reg; 164*5c4f8d80SVincenzo Maffione 165*5c4f8d80SVincenzo Maffione /* all the fields below should be considered read-only */ 166*5c4f8d80SVincenzo Maffione 167*5c4f8d80SVincenzo Maffione /* if the same context is used throughout the program, d1->mem == 168*5c4f8d80SVincenzo Maffione * d2->mem iff d1 and d2 are using the memory region (i.e., zero 169*5c4f8d80SVincenzo Maffione * copy is possible between the two ports) 170*5c4f8d80SVincenzo Maffione */ 171*5c4f8d80SVincenzo Maffione struct nmem_d *mem; 172*5c4f8d80SVincenzo Maffione 173*5c4f8d80SVincenzo Maffione /* the nmctx used when this nmport_d was created */ 174*5c4f8d80SVincenzo Maffione struct nmctx *ctx; 175*5c4f8d80SVincenzo Maffione 176*5c4f8d80SVincenzo Maffione int register_done; /* nmport_register() has been called */ 177*5c4f8d80SVincenzo Maffione int mmap_done; /* nmport_mmap() has been called */ 178*5c4f8d80SVincenzo Maffione /* pointer to the extmem option contained in the hdr options, if any */ 179*5c4f8d80SVincenzo Maffione struct nmreq_opt_extmem *extmem; 180*5c4f8d80SVincenzo Maffione 181*5c4f8d80SVincenzo Maffione /* the fields below are compatible with nm_open() */ 182*5c4f8d80SVincenzo Maffione int fd; /* "/dev/netmap", -1 if not open */ 183*5c4f8d80SVincenzo Maffione struct netmap_if *nifp; /* pointer to the netmap_if */ 184*5c4f8d80SVincenzo Maffione uint16_t first_tx_ring; 185*5c4f8d80SVincenzo Maffione uint16_t last_tx_ring; 186*5c4f8d80SVincenzo Maffione uint16_t first_rx_ring; 187*5c4f8d80SVincenzo Maffione uint16_t last_rx_ring; 188*5c4f8d80SVincenzo Maffione uint16_t cur_tx_ring; /* used by nmport_inject */ 189*5c4f8d80SVincenzo Maffione uint16_t cur_rx_ring; 190*5c4f8d80SVincenzo Maffione 191*5c4f8d80SVincenzo Maffione /* LIFO list of cleanup functions (used internally) */ 192*5c4f8d80SVincenzo Maffione struct nmport_cleanup_d *clist; 193*5c4f8d80SVincenzo Maffione }; 194*5c4f8d80SVincenzo Maffione 195*5c4f8d80SVincenzo Maffione /* nmport_open - opens a port from a portspec 196*5c4f8d80SVincenzo Maffione * @portspec the port opening specification 197*5c4f8d80SVincenzo Maffione * 198*5c4f8d80SVincenzo Maffione * If successful, the function returns a new nmport_d describing a netmap 199*5c4f8d80SVincenzo Maffione * port, opened according to the port specification, ready to be used for rx 200*5c4f8d80SVincenzo Maffione * and/or tx. 201*5c4f8d80SVincenzo Maffione * 202*5c4f8d80SVincenzo Maffione * The rings available for tx are in the [first_tx_ring, last_tx_ring] 203*5c4f8d80SVincenzo Maffione * interval, and similarly for rx. One or both intervals may be empty. 204*5c4f8d80SVincenzo Maffione * 205*5c4f8d80SVincenzo Maffione * When done using it, the nmport_d descriptor must be closed using 206*5c4f8d80SVincenzo Maffione * nmport_close(). 207*5c4f8d80SVincenzo Maffione * 208*5c4f8d80SVincenzo Maffione * In case of error, NULL is returned, errno is set to some error, and an 209*5c4f8d80SVincenzo Maffione * error message is sent through the error() method of the current context. 210*5c4f8d80SVincenzo Maffione */ 211*5c4f8d80SVincenzo Maffione struct nmport_d * nmport_open(const char *portspec); 212*5c4f8d80SVincenzo Maffione 213*5c4f8d80SVincenzo Maffione /* nport_close - close a netmap port 214*5c4f8d80SVincenzo Maffione * @d the port we want to close 215*5c4f8d80SVincenzo Maffione * 216*5c4f8d80SVincenzo Maffione * Undoes the actions performed by the nmport_open that created d, then 217*5c4f8d80SVincenzo Maffione * frees the descriptor. 218*5c4f8d80SVincenzo Maffione */ 219*5c4f8d80SVincenzo Maffione void nmport_close(struct nmport_d *d); 220*5c4f8d80SVincenzo Maffione 221*5c4f8d80SVincenzo Maffione /* nmport_inject - sends a packet 222*5c4f8d80SVincenzo Maffione * @d the port through which we want to send 223*5c4f8d80SVincenzo Maffione * @buf base address of the packet 224*5c4f8d80SVincenzo Maffione * @size its size in bytes 225*5c4f8d80SVincenzo Maffione * 226*5c4f8d80SVincenzo Maffione * Sends a packet using the cur_tx_ring and updates the index 227*5c4f8d80SVincenzo Maffione * to use all available tx rings in turn. Note: the packet is copied. 228*5c4f8d80SVincenzo Maffione * 229*5c4f8d80SVincenzo Maffione * Returns 0 on success an -1 on error. 230*5c4f8d80SVincenzo Maffione */ 231*5c4f8d80SVincenzo Maffione int nmport_inject(struct nmport_d *d, const void *buf, size_t size); 232*5c4f8d80SVincenzo Maffione 233*5c4f8d80SVincenzo Maffione /* 234*5c4f8d80SVincenzo Maffione * the functions below can be used to split the functionality of 235*5c4f8d80SVincenzo Maffione * nmport_open when special features (e.g., extra buffers) are needed 236*5c4f8d80SVincenzo Maffione * 237*5c4f8d80SVincenzo Maffione * The relation among the functions is as follows: 238*5c4f8d80SVincenzo Maffione * 239*5c4f8d80SVincenzo Maffione * |nmport_new 240*5c4f8d80SVincenzo Maffione * |nmport_prepare = | 241*5c4f8d80SVincenzo Maffione * | |nmport_parse 242*5c4f8d80SVincenzo Maffione * nmport_open =| 243*5c4f8d80SVincenzo Maffione * | |nmport_register 244*5c4f8d80SVincenzo Maffione * |nmport_open_desc =| 245*5c4f8d80SVincenzo Maffione * |nmport_mmap 246*5c4f8d80SVincenzo Maffione * 247*5c4f8d80SVincenzo Maffione */ 248*5c4f8d80SVincenzo Maffione 249*5c4f8d80SVincenzo Maffione /* nmport_new - create a new nmport_d 250*5c4f8d80SVincenzo Maffione * 251*5c4f8d80SVincenzo Maffione * Creates a new nmport_d using the malloc() method of the current default 252*5c4f8d80SVincenzo Maffione * context. Returns NULL on error, setting errno to an error value. 253*5c4f8d80SVincenzo Maffione */ 254*5c4f8d80SVincenzo Maffione struct nmport_d *nmport_new(void); 255*5c4f8d80SVincenzo Maffione 256*5c4f8d80SVincenzo Maffione /* nmport_parse - fills the nmport_d netmap-register request 257*5c4f8d80SVincenzo Maffione * @d the nmport to be filled 258*5c4f8d80SVincenzo Maffione * @portspec the port opening specification 259*5c4f8d80SVincenzo Maffione * 260*5c4f8d80SVincenzo Maffione * This function parses the portspec and initizalizes the @d->hdr and @d->reg 261*5c4f8d80SVincenzo Maffione * fields. It may need to allocate a list of options. If an extmem option is 262*5c4f8d80SVincenzo Maffione * found, it may also mmap() the corresponding file. 263*5c4f8d80SVincenzo Maffione * 264*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 265*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 266*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 267*5c4f8d80SVincenzo Maffione */ 268*5c4f8d80SVincenzo Maffione int nmport_parse(struct nmport_d *d, const char *portspec); 269*5c4f8d80SVincenzo Maffione 270*5c4f8d80SVincenzo Maffione /* nmport_register - registers the port with netmap 271*5c4f8d80SVincenzo Maffione * @d the nmport to be registered 272*5c4f8d80SVincenzo Maffione * 273*5c4f8d80SVincenzo Maffione * This function obtains a netmap file descriptor and registers the port with 274*5c4f8d80SVincenzo Maffione * netmap. The @d->hdr and @d->reg data structures must have been previously 275*5c4f8d80SVincenzo Maffione * initialized (via nmport_parse() or otherwise). 276*5c4f8d80SVincenzo Maffione * 277*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 278*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 279*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 280*5c4f8d80SVincenzo Maffione */ 281*5c4f8d80SVincenzo Maffione int nmport_register(struct nmport_d *); 282*5c4f8d80SVincenzo Maffione 283*5c4f8d80SVincenzo Maffione /* nmport_mmap - maps the port resources into the process memory 284*5c4f8d80SVincenzo Maffione * @d the nmport to be mapped 285*5c4f8d80SVincenzo Maffione * 286*5c4f8d80SVincenzo Maffione * The port must have been previously been registered using nmport_register. 287*5c4f8d80SVincenzo Maffione * 288*5c4f8d80SVincenzo Maffione * Note that if extmem is used (either via an option or by calling an 289*5c4f8d80SVincenzo Maffione * nmport_extmem_* function before nmport_register()), no new mmap() is issued. 290*5c4f8d80SVincenzo Maffione * 291*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 292*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 293*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 294*5c4f8d80SVincenzo Maffione */ 295*5c4f8d80SVincenzo Maffione int nmport_mmap(struct nmport_d *); 296*5c4f8d80SVincenzo Maffione 297*5c4f8d80SVincenzo Maffione /* the following functions undo the actions of nmport_new(), nmport_parse(), 298*5c4f8d80SVincenzo Maffione * nmport_register() and nmport_mmap(), respectively. 299*5c4f8d80SVincenzo Maffione */ 300*5c4f8d80SVincenzo Maffione void nmport_delete(struct nmport_d *); 301*5c4f8d80SVincenzo Maffione void nmport_undo_parse(struct nmport_d *); 302*5c4f8d80SVincenzo Maffione void nmport_undo_register(struct nmport_d *); 303*5c4f8d80SVincenzo Maffione void nmport_undo_mmap(struct nmport_d *); 304*5c4f8d80SVincenzo Maffione 305*5c4f8d80SVincenzo Maffione /* nmport_prepare - create a port descriptor, but do not open it 306*5c4f8d80SVincenzo Maffione * @portspec the port opening specification 307*5c4f8d80SVincenzo Maffione * 308*5c4f8d80SVincenzo Maffione * This functions creates a new nmport_d and initializes it according to 309*5c4f8d80SVincenzo Maffione * @portspec. It is equivalent to nmport_new() followed by nmport_parse(). 310*5c4f8d80SVincenzo Maffione * 311*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 312*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 313*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 314*5c4f8d80SVincenzo Maffione */ 315*5c4f8d80SVincenzo Maffione struct nmport_d *nmport_prepare(const char *portspec); 316*5c4f8d80SVincenzo Maffione 317*5c4f8d80SVincenzo Maffione /* nmport_open_desc - open an initialized port descriptor 318*5c4f8d80SVincenzo Maffione * @d the descriptor we want to open 319*5c4f8d80SVincenzo Maffione * 320*5c4f8d80SVincenzo Maffione * Registers the port with netmap and maps the rings and buffers into the 321*5c4f8d80SVincenzo Maffione * process memory. It is equivalent to nmport_register() followed by 322*5c4f8d80SVincenzo Maffione * nmport_mmap(). 323*5c4f8d80SVincenzo Maffione * 324*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 325*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 326*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 327*5c4f8d80SVincenzo Maffione */ 328*5c4f8d80SVincenzo Maffione int nmport_open_desc(struct nmport_d *d); 329*5c4f8d80SVincenzo Maffione 330*5c4f8d80SVincenzo Maffione /* the following functions undo the actions of nmport_prepare() 331*5c4f8d80SVincenzo Maffione * and nmport_open_desc(), respectively. 332*5c4f8d80SVincenzo Maffione */ 333*5c4f8d80SVincenzo Maffione void nmport_undo_prepare(struct nmport_d *); 334*5c4f8d80SVincenzo Maffione void nmport_undo_open_desc(struct nmport_d *); 335*5c4f8d80SVincenzo Maffione 336*5c4f8d80SVincenzo Maffione /* nmport_clone - copy an nmport_d 337*5c4f8d80SVincenzo Maffione * @d the nmport_d we want to copy 338*5c4f8d80SVincenzo Maffione * 339*5c4f8d80SVincenzo Maffione * Copying an nmport_d by hand should be avoided, since adjustments are needed 340*5c4f8d80SVincenzo Maffione * and some part of the state cannot be easily duplicated. This function 341*5c4f8d80SVincenzo Maffione * creates a copy of @d in a safe way. The returned nmport_d contains 342*5c4f8d80SVincenzo Maffione * nmreq_header and nmreq_register structures equivalent to those contained in 343*5c4f8d80SVincenzo Maffione * @d, except for the option list, which is ignored. The returned nmport_d is 344*5c4f8d80SVincenzo Maffione * already nmport_prepare()d, but it must still be nmport_open_desc()ed. The 345*5c4f8d80SVincenzo Maffione * new nmport_d uses the same nmctx as @d. 346*5c4f8d80SVincenzo Maffione * 347*5c4f8d80SVincenzo Maffione * If extmem was used for @d, then @d cannot be nmport_clone()d until it has 348*5c4f8d80SVincenzo Maffione * been nmport_register()ed. 349*5c4f8d80SVincenzo Maffione * 350*5c4f8d80SVincenzo Maffione * In case of error, the function returns NULL, sets errno to an error value 351*5c4f8d80SVincenzo Maffione * and sends an error message to the nmctx error() method. 352*5c4f8d80SVincenzo Maffione */ 353*5c4f8d80SVincenzo Maffione struct nmport_d *nmport_clone(struct nmport_d *); 354*5c4f8d80SVincenzo Maffione 355*5c4f8d80SVincenzo Maffione /* nmport_extmem - use extmem for this port 356*5c4f8d80SVincenzo Maffione * @d the port we want to use the extmem for 357*5c4f8d80SVincenzo Maffione * @base the base address of the extmem region 358*5c4f8d80SVincenzo Maffione * @size the size in bytes of the extmem region 359*5c4f8d80SVincenzo Maffione * 360*5c4f8d80SVincenzo Maffione * the memory that contains the netmap ifs, rings and buffers is usually 361*5c4f8d80SVincenzo Maffione * allocated by netmap and later mmap()ed by the applications. It is sometimes 362*5c4f8d80SVincenzo Maffione * useful to reverse this process, by having the applications allocate some 363*5c4f8d80SVincenzo Maffione * memory (through mmap() or otherwise) and then let netmap use it. The extmem 364*5c4f8d80SVincenzo Maffione * option can be used to implement this latter strategy. The option can be 365*5c4f8d80SVincenzo Maffione * passed through the portspec using the '@extmem:...' syntax, or 366*5c4f8d80SVincenzo Maffione * programmatically by calling nmport_extmem() or nmport_extmem_from_file() 367*5c4f8d80SVincenzo Maffione * between nmport_parse() and nmport_register() (or between nmport_prepare() 368*5c4f8d80SVincenzo Maffione * and nmport_open_desc()). 369*5c4f8d80SVincenzo Maffione * 370*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 371*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 372*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 373*5c4f8d80SVincenzo Maffione */ 374*5c4f8d80SVincenzo Maffione int nmport_extmem(struct nmport_d *d, void *base, size_t size); 375*5c4f8d80SVincenzo Maffione 376*5c4f8d80SVincenzo Maffione /* nmport_extmem_from_file - use the extmem obtained by mapping a file 377*5c4f8d80SVincenzo Maffione * @d the port we want to use the extmem for 378*5c4f8d80SVincenzo Maffione * @fname path of the file we want to map 379*5c4f8d80SVincenzo Maffione * 380*5c4f8d80SVincenzo Maffione * This works like nmport_extmem, but the extmem memory is obtained by 381*5c4f8d80SVincenzo Maffione * mmap()ping @fname. nmport_close() will also automatically munmap() the file. 382*5c4f8d80SVincenzo Maffione * 383*5c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 384*5c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 385*5c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 386*5c4f8d80SVincenzo Maffione */ 387*5c4f8d80SVincenzo Maffione int nmport_extmem_from_file(struct nmport_d *d, const char *fname); 388*5c4f8d80SVincenzo Maffione 389*5c4f8d80SVincenzo Maffione /* nmport_extmem_getinfo - opbtai a pointer to the extmem configuration 390*5c4f8d80SVincenzo Maffione * @d the port we want to obtain the pointer from 391*5c4f8d80SVincenzo Maffione * 392*5c4f8d80SVincenzo Maffione * Returns a pointer to the nmreq_pools_info structure containing the 393*5c4f8d80SVincenzo Maffione * configuration of the extmem attached to port @d, or NULL if no extmem 394*5c4f8d80SVincenzo Maffione * is attached. This can be used to set the desired configuration before 395*5c4f8d80SVincenzo Maffione * registering the port, or to read the actual configuration after 396*5c4f8d80SVincenzo Maffione * registration. 397*5c4f8d80SVincenzo Maffione */ 398*5c4f8d80SVincenzo Maffione struct nmreq_pools_info* nmport_extmem_getinfo(struct nmport_d *d); 399*5c4f8d80SVincenzo Maffione 400*5c4f8d80SVincenzo Maffione 401*5c4f8d80SVincenzo Maffione /* enable/disable options 402*5c4f8d80SVincenzo Maffione * 403*5c4f8d80SVincenzo Maffione * These functions can be used to disable options that the application cannot 404*5c4f8d80SVincenzo Maffione * or doesn't want to handle, or to enable options that require special support 405*5c4f8d80SVincenzo Maffione * from the application and are, therefore, disabled by default. Disabled 406*5c4f8d80SVincenzo Maffione * options will cause an error if encountered during option parsing. 407*5c4f8d80SVincenzo Maffione * 408*5c4f8d80SVincenzo Maffione * If the option is unknown, nmport_disable_option is a NOP, while 409*5c4f8d80SVincenzo Maffione * nmport_enable_option returns -1 and sets errno to EOPNOTSUPP. 410*5c4f8d80SVincenzo Maffione * 411*5c4f8d80SVincenzo Maffione * These functions are not threadsafe and are meant to be used at the beginning 412*5c4f8d80SVincenzo Maffione * of the program. 413*5c4f8d80SVincenzo Maffione */ 414*5c4f8d80SVincenzo Maffione void nmport_disable_option(const char *opt); 415*5c4f8d80SVincenzo Maffione int nmport_enable_option(const char *opt); 416*5c4f8d80SVincenzo Maffione 417*5c4f8d80SVincenzo Maffione /* nmreq manipulation 418*5c4f8d80SVincenzo Maffione * 419*5c4f8d80SVincenzo Maffione * nmreq_header_init - initialize an nmreq_header 420*5c4f8d80SVincenzo Maffione * @hdr the nmreq_header to initialize 421*5c4f8d80SVincenzo Maffione * @reqtype the kind of netmap request 422*5c4f8d80SVincenzo Maffione * @body the body of the request 423*5c4f8d80SVincenzo Maffione * 424*5c4f8d80SVincenzo Maffione * Initialize the nr_version, nr_reqtype and nr_body fields of *@hdr. 425*5c4f8d80SVincenzo Maffione * The other fields are set to zero. 426*5c4f8d80SVincenzo Maffione */ 427*5c4f8d80SVincenzo Maffione void nmreq_header_init(struct nmreq_header *hdr, uint16_t reqtype, void *body); 428*5c4f8d80SVincenzo Maffione 429*5c4f8d80SVincenzo Maffione /* 430*5c4f8d80SVincenzo Maffione * These functions allow for finer grained parsing of portspecs. They are used 431*5c4f8d80SVincenzo Maffione * internally by nmport_parse(). 432*5c4f8d80SVincenzo Maffione */ 433*5c4f8d80SVincenzo Maffione 434*5c4f8d80SVincenzo Maffione /* nmreq_header_decode - initialize an nmreq_header 435*5c4f8d80SVincenzo Maffione * @ppspec: (in/out) pointer to a pointer to the portspec 436*5c4f8d80SVincenzo Maffione * @hdr: pointer to the nmreq_header to be initialized 437*5c4f8d80SVincenzo Maffione * @ctx: pointer to the nmctx to use (for errors) 438*5c4f8d80SVincenzo Maffione * 439*5c4f8d80SVincenzo Maffione * This function fills the @hdr the nr_name field with the port name extracted 440*5c4f8d80SVincenzo Maffione * from *@pifname. The other fields of *@hdr are unchanged. The @pifname is 441*5c4f8d80SVincenzo Maffione * updated to point at the first char past the port name. 442*5c4f8d80SVincenzo Maffione * 443*5c4f8d80SVincenzo Maffione * Returns 0 on success. In case of error, -1 is returned with errno set to 444*5c4f8d80SVincenzo Maffione * EINVAL, @pifname is unchanged, *@hdr is also unchanged, and an error message 445*5c4f8d80SVincenzo Maffione * is sent through @ctx->error(). 446*5c4f8d80SVincenzo Maffione */ 447*5c4f8d80SVincenzo Maffione int nmreq_header_decode(const char **ppspec, struct nmreq_header *hdr, 448*5c4f8d80SVincenzo Maffione struct nmctx *ctx); 449*5c4f8d80SVincenzo Maffione 450*5c4f8d80SVincenzo Maffione /* nmreq_regiter_decode - initialize an nmreq_register 451*5c4f8d80SVincenzo Maffione * @pmode: (in/out) pointer to a pointer to an opening mode 452*5c4f8d80SVincenzo Maffione * @reg: pointer to the nmreq_register to be initialized 453*5c4f8d80SVincenzo Maffione * @ctx: pointer to the nmctx to use (for errors) 454*5c4f8d80SVincenzo Maffione * 455*5c4f8d80SVincenzo Maffione * This function fills the nr_mode, nr_ringid, nr_flags and nr_mem_id fields of 456*5c4f8d80SVincenzo Maffione * the structure pointed by @reg, according to the opening mode specified by 457*5c4f8d80SVincenzo Maffione * *@pmode. The other fields of *@reg are unchanged. The @pmode is updated to 458*5c4f8d80SVincenzo Maffione * point at the first char past the opening mode. 459*5c4f8d80SVincenzo Maffione * 460*5c4f8d80SVincenzo Maffione * If a '@' is encountered followed by something which is not a number, parsing 461*5c4f8d80SVincenzo Maffione * stops (without error) and @pmode is left pointing at the '@' char. The 462*5c4f8d80SVincenzo Maffione * nr_mode, nr_ringid and nr_flags fields are still updated, but nr_mem_id is 463*5c4f8d80SVincenzo Maffione * not touched and the interpretation of the '@' field is left to the caller. 464*5c4f8d80SVincenzo Maffione * 465*5c4f8d80SVincenzo Maffione * Returns 0 on success. In case of error, -1 is returned with errno set to 466*5c4f8d80SVincenzo Maffione * EINVAL, @pmode is unchanged, *@reg is also unchanged, and an error message 467*5c4f8d80SVincenzo Maffione * is sent through @ctx->error(). 468*5c4f8d80SVincenzo Maffione */ 469*5c4f8d80SVincenzo Maffione int nmreq_register_decode(const char **pmode, struct nmreq_register *reg, 470*5c4f8d80SVincenzo Maffione struct nmctx *ctx); 471*5c4f8d80SVincenzo Maffione 472*5c4f8d80SVincenzo Maffione /* nmreq_options_decode - parse the "options" part of the portspec 473*5c4f8d80SVincenzo Maffione * @opt: pointer to the option list 474*5c4f8d80SVincenzo Maffione * @parsers: list of option parsers 475*5c4f8d80SVincenzo Maffione * @token: token to pass to each parser 476*5c4f8d80SVincenzo Maffione * @ctx: pointer to the nmctx to use (for errors and malloc/free) 477*5c4f8d80SVincenzo Maffione * 478*5c4f8d80SVincenzo Maffione * This function parses each option in @opt. Each option is matched (based on 479*5c4f8d80SVincenzo Maffione * the "option" prefix) to a corresponding parser in @parsers. The function 480*5c4f8d80SVincenzo Maffione * checks that the syntax is appropriate for the parser and it assigns all the 481*5c4f8d80SVincenzo Maffione * keys mentioned in the option. It then passes control to the parser, to 482*5c4f8d80SVincenzo Maffione * interpret the keys values. 483*5c4f8d80SVincenzo Maffione * 484*5c4f8d80SVincenzo Maffione * Returns 0 on success. In case of error, -1 is returned, errno is set to an 485*5c4f8d80SVincenzo Maffione * error value and a message is sent to @ctx->error(). The effects of partially 486*5c4f8d80SVincenzo Maffione * interpreted options may not be undone. 487*5c4f8d80SVincenzo Maffione */ 488*5c4f8d80SVincenzo Maffione struct nmreq_opt_parser; 489*5c4f8d80SVincenzo Maffione int nmreq_options_decode(const char *opt, struct nmreq_opt_parser *parsers, 490*5c4f8d80SVincenzo Maffione void *token, struct nmctx *ctx); 491*5c4f8d80SVincenzo Maffione 492*5c4f8d80SVincenzo Maffione struct nmreq_parse_ctx; 493*5c4f8d80SVincenzo Maffione /* type of the option-parsers callbacks */ 494*5c4f8d80SVincenzo Maffione typedef int (*nmreq_opt_parser_cb)(struct nmreq_parse_ctx *); 495*5c4f8d80SVincenzo Maffione 496*5c4f8d80SVincenzo Maffione #define NMREQ_OPT_MAXKEYS 16 /* max nr of recognized keys per option */ 497*5c4f8d80SVincenzo Maffione 498*5c4f8d80SVincenzo Maffione /* struct nmreq_opt_key - describes an option key */ 499*5c4f8d80SVincenzo Maffione struct nmreq_opt_key { 500*5c4f8d80SVincenzo Maffione const char *key; /* the key name */ 501*5c4f8d80SVincenzo Maffione int id; /* its position in the parse context */ 502*5c4f8d80SVincenzo Maffione unsigned int flags; 503*5c4f8d80SVincenzo Maffione #define NMREQ_OPTK_ALLOWEMPTY (1U << 0) /* =value may be omitted */ 504*5c4f8d80SVincenzo Maffione #define NMREQ_OPTK_MUSTSET (1U << 1) /* the key is mandatory */ 505*5c4f8d80SVincenzo Maffione #define NMREQ_OPTK_DEFAULT (1U << 2) /* this is the default key */ 506*5c4f8d80SVincenzo Maffione }; 507*5c4f8d80SVincenzo Maffione 508*5c4f8d80SVincenzo Maffione /* struct nmreq_opt_parser - describes an option parser */ 509*5c4f8d80SVincenzo Maffione struct nmreq_opt_parser { 510*5c4f8d80SVincenzo Maffione const char *prefix; /* matches one option prefix */ 511*5c4f8d80SVincenzo Maffione nmreq_opt_parser_cb parse; /* the parse callback */ 512*5c4f8d80SVincenzo Maffione int default_key; /* which option is the default if the 513*5c4f8d80SVincenzo Maffione parser is multi-key (-1 if none) */ 514*5c4f8d80SVincenzo Maffione int nr_keys; 515*5c4f8d80SVincenzo Maffione unsigned int flags; 516*5c4f8d80SVincenzo Maffione #define NMREQ_OPTF_DISABLED (1U << 0) 517*5c4f8d80SVincenzo Maffione #define NMREQ_OPTF_ALLOWEMPTY (1U << 1) /* =value can be omitted */ 518*5c4f8d80SVincenzo Maffione 519*5c4f8d80SVincenzo Maffione struct nmreq_opt_parser *next; /* list of options */ 520*5c4f8d80SVincenzo Maffione 521*5c4f8d80SVincenzo Maffione /* recognized keys */ 522*5c4f8d80SVincenzo Maffione struct nmreq_opt_key keys[NMREQ_OPT_MAXKEYS]; 523*5c4f8d80SVincenzo Maffione } __attribute__((aligned(16))); 524*5c4f8d80SVincenzo Maffione 525*5c4f8d80SVincenzo Maffione /* struct nmreq_parse_ctx - the parse context received by the parse callback */ 526*5c4f8d80SVincenzo Maffione struct nmreq_parse_ctx { 527*5c4f8d80SVincenzo Maffione struct nmctx *ctx; /* the nmctx for errors and malloc/free */ 528*5c4f8d80SVincenzo Maffione void *token; /* the token passed to nmreq_options_parse */ 529*5c4f8d80SVincenzo Maffione 530*5c4f8d80SVincenzo Maffione /* the value (i.e., the part after the = sign) of each recognized key 531*5c4f8d80SVincenzo Maffione * is assigned to the corresponding entry in this array, based on the 532*5c4f8d80SVincenzo Maffione * key id. Unassigned keys are left at NULL. 533*5c4f8d80SVincenzo Maffione */ 534*5c4f8d80SVincenzo Maffione const char *keys[NMREQ_OPT_MAXKEYS]; 535*5c4f8d80SVincenzo Maffione }; 536*5c4f8d80SVincenzo Maffione 537*5c4f8d80SVincenzo Maffione /* nmreq_get_mem_id - get the mem_id of the given port 538*5c4f8d80SVincenzo Maffione * @portname pointer to a pointer to the portname 539*5c4f8d80SVincenzo Maffione * @ctx pointer to the nmctx to use (for errors) 540*5c4f8d80SVincenzo Maffione * 541*5c4f8d80SVincenzo Maffione * *@portname must point to a substem:vpname porname, possibly followed by 542*5c4f8d80SVincenzo Maffione * something else. 543*5c4f8d80SVincenzo Maffione * 544*5c4f8d80SVincenzo Maffione * If successful, returns the mem_id of *@portname and moves @portname past the 545*5c4f8d80SVincenzo Maffione * subsystem:vpname part of the input. In case of error it returns -1, sets 546*5c4f8d80SVincenzo Maffione * errno to an error value and sends an error message to ctx->error(). 547*5c4f8d80SVincenzo Maffione */ 548*5c4f8d80SVincenzo Maffione int32_t nmreq_get_mem_id(const char **portname, struct nmctx *ctx); 549*5c4f8d80SVincenzo Maffione 550*5c4f8d80SVincenzo Maffione /* option list manipulation */ 551*5c4f8d80SVincenzo Maffione void nmreq_push_option(struct nmreq_header *, struct nmreq_option *); 552*5c4f8d80SVincenzo Maffione void nmreq_remove_option(struct nmreq_header *, struct nmreq_option *); 553*5c4f8d80SVincenzo Maffione struct nmreq_option *nmreq_find_option(struct nmreq_header *, uint32_t); 554*5c4f8d80SVincenzo Maffione void nmreq_free_options(struct nmreq_header *); 555*5c4f8d80SVincenzo Maffione const char* nmreq_option_name(uint32_t); 556*5c4f8d80SVincenzo Maffione #define nmreq_foreach_option(h_, o_) \ 557*5c4f8d80SVincenzo Maffione for ((o_) = (struct nmreq_option *)((h_)->nr_options);\ 558*5c4f8d80SVincenzo Maffione (o_) != NULL;\ 559*5c4f8d80SVincenzo Maffione (o_) = (struct nmreq_option *)((o_)->nro_next)) 560*5c4f8d80SVincenzo Maffione 561*5c4f8d80SVincenzo Maffione /* nmctx manipulation */ 562*5c4f8d80SVincenzo Maffione 563*5c4f8d80SVincenzo Maffione /* the nmctx serves a few purposes: 564*5c4f8d80SVincenzo Maffione * 565*5c4f8d80SVincenzo Maffione * - maintain a list of all memory regions open by the program, so that two 566*5c4f8d80SVincenzo Maffione * ports that are using the same region (as identified by the mem_id) will 567*5c4f8d80SVincenzo Maffione * point to the same nmem_d instance. 568*5c4f8d80SVincenzo Maffione * 569*5c4f8d80SVincenzo Maffione * - allow the user to specify how to lock accesses to the above list, if 570*5c4f8d80SVincenzo Maffione * needed (lock() callback) 571*5c4f8d80SVincenzo Maffione * 572*5c4f8d80SVincenzo Maffione * - allow the user to specify how error messages should be delivered (error() 573*5c4f8d80SVincenzo Maffione * callback) 574*5c4f8d80SVincenzo Maffione * 575*5c4f8d80SVincenzo Maffione * - select the verbosity of the library (verbose field); if verbose==0, no 576*5c4f8d80SVincenzo Maffione * errors are sent to the error() callback 577*5c4f8d80SVincenzo Maffione * 578*5c4f8d80SVincenzo Maffione * - allow the user to override the malloc/free functions used by the library 579*5c4f8d80SVincenzo Maffione * (malloc() and free() callbacks) 580*5c4f8d80SVincenzo Maffione * 581*5c4f8d80SVincenzo Maffione */ 582*5c4f8d80SVincenzo Maffione typedef void (*nmctx_error_cb)(struct nmctx *, const char *); 583*5c4f8d80SVincenzo Maffione typedef void *(*nmctx_malloc_cb)(struct nmctx *,size_t); 584*5c4f8d80SVincenzo Maffione typedef void (*nmctx_free_cb)(struct nmctx *,void *); 585*5c4f8d80SVincenzo Maffione typedef void (*nmctx_lock_cb)(struct nmctx *, int); 586*5c4f8d80SVincenzo Maffione 587*5c4f8d80SVincenzo Maffione struct nmctx { 588*5c4f8d80SVincenzo Maffione int verbose; 589*5c4f8d80SVincenzo Maffione nmctx_error_cb error; 590*5c4f8d80SVincenzo Maffione nmctx_malloc_cb malloc; 591*5c4f8d80SVincenzo Maffione nmctx_free_cb free; 592*5c4f8d80SVincenzo Maffione nmctx_lock_cb lock; 593*5c4f8d80SVincenzo Maffione 594*5c4f8d80SVincenzo Maffione struct nmem_d *mem_descs; 595*5c4f8d80SVincenzo Maffione }; 596*5c4f8d80SVincenzo Maffione 597*5c4f8d80SVincenzo Maffione /* nmctx_get - obtain a pointer to the current default context */ 598*5c4f8d80SVincenzo Maffione struct nmctx *nmctx_get(void); 599*5c4f8d80SVincenzo Maffione 600*5c4f8d80SVincenzo Maffione /* nmctx_set_default - change the default context 601*5c4f8d80SVincenzo Maffione * @ctx pointer to the new context 602*5c4f8d80SVincenzo Maffione * 603*5c4f8d80SVincenzo Maffione * Returns a pointer to the previous default context. 604*5c4f8d80SVincenzo Maffione */ 605*5c4f8d80SVincenzo Maffione struct nmctx *nmctx_set_default(struct nmctx *ctx); 606*5c4f8d80SVincenzo Maffione 607*5c4f8d80SVincenzo Maffione /* internal functions and data structures */ 608*5c4f8d80SVincenzo Maffione 609*5c4f8d80SVincenzo Maffione /* struct nmem_d - describes a memory region currently used */ 610*5c4f8d80SVincenzo Maffione struct nmem_d { 611*5c4f8d80SVincenzo Maffione uint16_t mem_id; /* the region netmap identifier */ 612*5c4f8d80SVincenzo Maffione int refcount; /* how many nmport_d's point here */ 613*5c4f8d80SVincenzo Maffione void *mem; /* memory region base address */ 614*5c4f8d80SVincenzo Maffione size_t size; /* memory region size */ 615*5c4f8d80SVincenzo Maffione int is_extmem; /* was it obtained via extmem? */ 616*5c4f8d80SVincenzo Maffione 617*5c4f8d80SVincenzo Maffione /* pointers for the circular list implementation. 618*5c4f8d80SVincenzo Maffione * The list head is the mem_descs filed in the nmctx 619*5c4f8d80SVincenzo Maffione */ 620*5c4f8d80SVincenzo Maffione struct nmem_d *next; 621*5c4f8d80SVincenzo Maffione struct nmem_d *prev; 622*5c4f8d80SVincenzo Maffione }; 623*5c4f8d80SVincenzo Maffione 624*5c4f8d80SVincenzo Maffione /* a trick to force the inclusion of libpthread only if requested. If 625*5c4f8d80SVincenzo Maffione * LIBNETMAP_NOTHREADSAFE is defined, no pthread symbol is imported. 626*5c4f8d80SVincenzo Maffione * 627*5c4f8d80SVincenzo Maffione * There is no need to actually call this function: the ((used)) attribute is 628*5c4f8d80SVincenzo Maffione * sufficient to include it in the image. 629*5c4f8d80SVincenzo Maffione */ 630*5c4f8d80SVincenzo Maffione static __attribute__((used)) void libnetmap_init(void) 631*5c4f8d80SVincenzo Maffione { 632*5c4f8d80SVincenzo Maffione #ifndef LIBNETMAP_NOTHREADSAFE 633*5c4f8d80SVincenzo Maffione extern int nmctx_threadsafe; 634*5c4f8d80SVincenzo Maffione /* dummy assignment to link-in the nmctx-pthread.o object. The proper 635*5c4f8d80SVincenzo Maffione * inizialization is performed only once in the library constructor 636*5c4f8d80SVincenzo Maffione * defined there. 637*5c4f8d80SVincenzo Maffione */ 638*5c4f8d80SVincenzo Maffione nmctx_threadsafe = 1; 639*5c4f8d80SVincenzo Maffione #endif /* LIBNETMAP_NOTHREADSAFE */ 640*5c4f8d80SVincenzo Maffione } 641*5c4f8d80SVincenzo Maffione 642*5c4f8d80SVincenzo Maffione /* nmctx_set_threadsafe - install a threadsafe default context 643*5c4f8d80SVincenzo Maffione * 644*5c4f8d80SVincenzo Maffione * called by the constructor in nmctx-pthread.o to initialize a lock and install 645*5c4f8d80SVincenzo Maffione * the lock() callback in the default context. 646*5c4f8d80SVincenzo Maffione */ 647*5c4f8d80SVincenzo Maffione void nmctx_set_threadsafe(void); 648*5c4f8d80SVincenzo Maffione 649*5c4f8d80SVincenzo Maffione /* nmctx_ferror - format and send an error message */ 650*5c4f8d80SVincenzo Maffione void nmctx_ferror(struct nmctx *, const char *, ...); 651*5c4f8d80SVincenzo Maffione /* nmctx_malloc - allocate memory */ 652*5c4f8d80SVincenzo Maffione void *nmctx_malloc(struct nmctx *, size_t); 653*5c4f8d80SVincenzo Maffione /* nmctx_free - free memory allocated via nmctx_malloc */ 654*5c4f8d80SVincenzo Maffione void nmctx_free(struct nmctx *, void *); 655*5c4f8d80SVincenzo Maffione /* nmctx_lock - lock the list of nmem_d */ 656*5c4f8d80SVincenzo Maffione void nmctx_lock(struct nmctx *); 657*5c4f8d80SVincenzo Maffione /* nmctx_unlock - unlock the list of nmem_d */ 658*5c4f8d80SVincenzo Maffione void nmctx_unlock(struct nmctx *); 659*5c4f8d80SVincenzo Maffione 660*5c4f8d80SVincenzo Maffione #endif /* LIBNETMAP_H_ */ 661