15c4f8d80SVincenzo Maffione /*- 25c4f8d80SVincenzo Maffione * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 35c4f8d80SVincenzo Maffione * 45c4f8d80SVincenzo Maffione * Copyright (C) 2018 Universita` di Pisa 55c4f8d80SVincenzo Maffione * All rights reserved. 65c4f8d80SVincenzo Maffione * 75c4f8d80SVincenzo Maffione * Redistribution and use in source and binary forms, with or without 85c4f8d80SVincenzo Maffione * modification, are permitted provided that the following conditions 95c4f8d80SVincenzo Maffione * are met: 105c4f8d80SVincenzo Maffione * 115c4f8d80SVincenzo Maffione * 1. Redistributions of source code must retain the above copyright 125c4f8d80SVincenzo Maffione * notice, this list of conditions and the following disclaimer. 135c4f8d80SVincenzo Maffione * 2. Redistributions in binary form must reproduce the above copyright 145c4f8d80SVincenzo Maffione * notice, this list of conditions and the following disclaimer in the 155c4f8d80SVincenzo Maffione * documentation and/or other materials provided with the distribution. 165c4f8d80SVincenzo Maffione * 175c4f8d80SVincenzo Maffione * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 185c4f8d80SVincenzo Maffione * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 195c4f8d80SVincenzo Maffione * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 205c4f8d80SVincenzo Maffione * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 215c4f8d80SVincenzo Maffione * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 225c4f8d80SVincenzo Maffione * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 235c4f8d80SVincenzo Maffione * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 245c4f8d80SVincenzo Maffione * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 255c4f8d80SVincenzo Maffione * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 265c4f8d80SVincenzo Maffione * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 275c4f8d80SVincenzo Maffione * SUCH DAMAGE. 285c4f8d80SVincenzo Maffione * $FreeBSD$ 295c4f8d80SVincenzo Maffione */ 305c4f8d80SVincenzo Maffione 315c4f8d80SVincenzo Maffione #ifndef LIBNETMAP_H_ 325c4f8d80SVincenzo Maffione #define LIBNETMAP_H_ 335c4f8d80SVincenzo Maffione /* if thread-safety is not needed, define LIBNETMAP_NOTHREADSAFE before including 345c4f8d80SVincenzo Maffione * this file. 355c4f8d80SVincenzo Maffione */ 365c4f8d80SVincenzo Maffione 375c4f8d80SVincenzo Maffione /* NOTE: we include net/netmap_user.h without defining NETMAP_WITH_LIBS, which 385c4f8d80SVincenzo Maffione * is deprecated. If you still need it, please define NETMAP_WITH_LIBS and 395c4f8d80SVincenzo Maffione * include net/netmap_user.h before including this file. 405c4f8d80SVincenzo Maffione */ 415c4f8d80SVincenzo Maffione #include <net/netmap_user.h> 425c4f8d80SVincenzo Maffione 435c4f8d80SVincenzo Maffione struct nmctx; 445c4f8d80SVincenzo Maffione struct nmport_d; 455c4f8d80SVincenzo Maffione struct nmem_d; 465c4f8d80SVincenzo Maffione 475c4f8d80SVincenzo Maffione /* 485c4f8d80SVincenzo Maffione * A port open specification (portspec for brevity) has the following syntax 495c4f8d80SVincenzo Maffione * (square brackets delimit optional parts): 505c4f8d80SVincenzo Maffione * 515c4f8d80SVincenzo Maffione * subsystem:vpname[mode][options] 525c4f8d80SVincenzo Maffione * 535c4f8d80SVincenzo Maffione * The "subsystem" is denoted by a prefix, possibly followed by an identifier. 545c4f8d80SVincenzo Maffione * There can be several kinds of subsystems, each one selected by a unique 555c4f8d80SVincenzo Maffione * prefix. Currently defined subsystems are: 565c4f8d80SVincenzo Maffione * 575c4f8d80SVincenzo Maffione * netmap (no id allowed) 585c4f8d80SVincenzo Maffione * the standard subsystem 595c4f8d80SVincenzo Maffione * 605c4f8d80SVincenzo Maffione * vale (followed by a possibly empty id) 615c4f8d80SVincenzo Maffione * the vpname is connected to a VALE switch identified by 625c4f8d80SVincenzo Maffione * the id (an empty id selects the default switch) 635c4f8d80SVincenzo Maffione * 645c4f8d80SVincenzo Maffione * The "vpname" has the following syntax: 655c4f8d80SVincenzo Maffione * 665c4f8d80SVincenzo Maffione * identifier or 675c4f8d80SVincenzo Maffione * identifier1{identifier2 or 685c4f8d80SVincenzo Maffione * identifier1}identifier2 695c4f8d80SVincenzo Maffione * 705c4f8d80SVincenzo Maffione * Identifiers are sequences of alphanumeric characters. The part that begins 715c4f8d80SVincenzo Maffione * with either '{' or '}', when present, denotes a netmap pipe opened in the 725c4f8d80SVincenzo Maffione * same memory region as the subsystem:indentifier1 port. 735c4f8d80SVincenzo Maffione * 745c4f8d80SVincenzo Maffione * The "mode" can be one of the following: 755c4f8d80SVincenzo Maffione * 765c4f8d80SVincenzo Maffione * ^ bind all host (sw) ring pairs 775c4f8d80SVincenzo Maffione * ^NN bind individual host ring pair 785c4f8d80SVincenzo Maffione * * bind host and NIC ring pairs 795c4f8d80SVincenzo Maffione * -NN bind individual NIC ring pair 805c4f8d80SVincenzo Maffione * @NN open the port in the NN memory region 815c4f8d80SVincenzo Maffione * a suffix starting with / and the following flags, 825c4f8d80SVincenzo Maffione * in any order: 835c4f8d80SVincenzo Maffione * x exclusive access 845c4f8d80SVincenzo Maffione * z zero copy monitor (both tx and rx) 855c4f8d80SVincenzo Maffione * t monitor tx side (copy monitor) 865c4f8d80SVincenzo Maffione * r monitor rx side (copy monitor) 875c4f8d80SVincenzo Maffione * R bind only RX ring(s) 885c4f8d80SVincenzo Maffione * T bind only TX ring(s) 895c4f8d80SVincenzo Maffione * 905c4f8d80SVincenzo Maffione * The "options" start at the first '@' character not followed by a number. 915c4f8d80SVincenzo Maffione * Each option starts with '@' and has the following syntax: 925c4f8d80SVincenzo Maffione * 935c4f8d80SVincenzo Maffione * option (flag option) 945c4f8d80SVincenzo Maffione * option=value (single key option) 955c4f8d80SVincenzo Maffione * option:key1=value1,key2=value2,... (multi-key option) 965c4f8d80SVincenzo Maffione * 975c4f8d80SVincenzo Maffione * For multi-key options, the keys can be assigned in any order, but they 985c4f8d80SVincenzo Maffione * cannot be assigned more than once. It is not necessary to assign all the 995c4f8d80SVincenzo Maffione * option keys: unmentioned keys will receive default values. Some multi-key 1005c4f8d80SVincenzo Maffione * options define a default key and also accept the single-key syntax, by 1015c4f8d80SVincenzo Maffione * assigning the value to this key. 1025c4f8d80SVincenzo Maffione * 1035c4f8d80SVincenzo Maffione * NOTE: Options may be silently ignored if the port is already open by some 1045c4f8d80SVincenzo Maffione * other process. 1055c4f8d80SVincenzo Maffione * 1065c4f8d80SVincenzo Maffione * The currently available options are (default keys, when defined, are marked 1075c4f8d80SVincenzo Maffione * with '*'): 1085c4f8d80SVincenzo Maffione * 1095c4f8d80SVincenzo Maffione * share (single-key) 1105c4f8d80SVincenzo Maffione * open the port in the same memory region used by the 1115c4f8d80SVincenzo Maffione * given port name (the port name must be given in 1125c4f8d80SVincenzo Maffione * subsystem:vpname form) 1135c4f8d80SVincenzo Maffione * 1145c4f8d80SVincenzo Maffione * conf (multi-key) 1155c4f8d80SVincenzo Maffione * specify the rings/slots numbers (effective only on 1165c4f8d80SVincenzo Maffione * ports that are created by the open operation itself, 1175c4f8d80SVincenzo Maffione * and ignored otherwise). 1185c4f8d80SVincenzo Maffione * 1195c4f8d80SVincenzo Maffione * The keys are: 1205c4f8d80SVincenzo Maffione * 1215c4f8d80SVincenzo Maffione * *rings number of tx and rx rings 1225c4f8d80SVincenzo Maffione * tx-rings number of tx rings 1235c4f8d80SVincenzo Maffione * rx-rings number of rx rings 1245c4f8d80SVincenzo Maffione * host-rings number of tx and rx host rings 1255c4f8d80SVincenzo Maffione * host-tx-rings number of host tx rings 1265c4f8d80SVincenzo Maffione * host-rx-rings number of host rx rings 1275c4f8d80SVincenzo Maffione * slots number of slots in each tx and rx 1285c4f8d80SVincenzo Maffione * ring 1295c4f8d80SVincenzo Maffione * tx-slots number of slots in each tx ring 1305c4f8d80SVincenzo Maffione * rx-slots number of slots in each rx ring 1315c4f8d80SVincenzo Maffione * 1325c4f8d80SVincenzo Maffione * (more specific keys override the less specific ones) 1335c4f8d80SVincenzo Maffione * All keys default to zero if not assigned, and the 1345c4f8d80SVincenzo Maffione * corresponding value will be chosen by netmap. 1355c4f8d80SVincenzo Maffione * 1365c4f8d80SVincenzo Maffione * extmem (multi-key) 1375c4f8d80SVincenzo Maffione * open the port in the memory region obtained by 1385c4f8d80SVincenzo Maffione * mmap()ing the given file. 1395c4f8d80SVincenzo Maffione * 1405c4f8d80SVincenzo Maffione * The keys are: 1415c4f8d80SVincenzo Maffione * 1425c4f8d80SVincenzo Maffione * *file the file to mmap 1435c4f8d80SVincenzo Maffione * if-num number of pre-allocated netmap_if's 1445c4f8d80SVincenzo Maffione * if-size size of each netmap_if 1455c4f8d80SVincenzo Maffione * ring-num number of pre-allocated netmap_ring's 1465c4f8d80SVincenzo Maffione * ring-size size of each netmap_ring 1475c4f8d80SVincenzo Maffione * buf-num number of pre-allocated buffers 1485c4f8d80SVincenzo Maffione * buf-size size of each buffer 1495c4f8d80SVincenzo Maffione * 1505c4f8d80SVincenzo Maffione * file must be assigned. The other keys default to zero, 1515c4f8d80SVincenzo Maffione * causing netmap to take the corresponding values from 1525c4f8d80SVincenzo Maffione * the priv_{if,ring,buf}_{num,size} sysctls. 1535c4f8d80SVincenzo Maffione * 154f8113f0aSVincenzo Maffione * offset (multi-key) 155f8113f0aSVincenzo Maffione * reserve (part of) the ptr fields as an offset field 156f8113f0aSVincenzo Maffione * and write an initial offset into them. 157f8113f0aSVincenzo Maffione * 158f8113f0aSVincenzo Maffione * The keys are: 159f8113f0aSVincenzo Maffione * 160f8113f0aSVincenzo Maffione * bits number of bits of ptr to use 161f8113f0aSVincenzo Maffione * *initial initial offset value 162f8113f0aSVincenzo Maffione * 163f8113f0aSVincenzo Maffione * initial must be assigned. If bits is omitted, it 164f8113f0aSVincenzo Maffione * defaults to the entire ptr field. The max offset is set 165f8113f0aSVincenzo Maffione * at the same value as the initial offset. Note that the 166f8113f0aSVincenzo Maffione * actual values may be increased by the kernel. 167f8113f0aSVincenzo Maffione * 168f8113f0aSVincenzo Maffione * This option is disabled by default (see 169f8113f0aSVincenzo Maffione * nmport_enable_option() below) 1705c4f8d80SVincenzo Maffione */ 1715c4f8d80SVincenzo Maffione 1725c4f8d80SVincenzo Maffione 1735c4f8d80SVincenzo Maffione /* nmport manipulation */ 1745c4f8d80SVincenzo Maffione 1755c4f8d80SVincenzo Maffione /* struct nmport_d - describes a netmap port */ 1765c4f8d80SVincenzo Maffione struct nmport_d { 1775c4f8d80SVincenzo Maffione /* see net/netmap.h for the definition of these fields */ 1785c4f8d80SVincenzo Maffione struct nmreq_header hdr; 1795c4f8d80SVincenzo Maffione struct nmreq_register reg; 1805c4f8d80SVincenzo Maffione 1815c4f8d80SVincenzo Maffione /* all the fields below should be considered read-only */ 1825c4f8d80SVincenzo Maffione 1835c4f8d80SVincenzo Maffione /* if the same context is used throughout the program, d1->mem == 1845c4f8d80SVincenzo Maffione * d2->mem iff d1 and d2 are using the memory region (i.e., zero 1855c4f8d80SVincenzo Maffione * copy is possible between the two ports) 1865c4f8d80SVincenzo Maffione */ 1875c4f8d80SVincenzo Maffione struct nmem_d *mem; 1885c4f8d80SVincenzo Maffione 1895c4f8d80SVincenzo Maffione /* the nmctx used when this nmport_d was created */ 1905c4f8d80SVincenzo Maffione struct nmctx *ctx; 1915c4f8d80SVincenzo Maffione 1925c4f8d80SVincenzo Maffione int register_done; /* nmport_register() has been called */ 1935c4f8d80SVincenzo Maffione int mmap_done; /* nmport_mmap() has been called */ 1945c4f8d80SVincenzo Maffione /* pointer to the extmem option contained in the hdr options, if any */ 1955c4f8d80SVincenzo Maffione struct nmreq_opt_extmem *extmem; 1965c4f8d80SVincenzo Maffione 1975c4f8d80SVincenzo Maffione /* the fields below are compatible with nm_open() */ 1985c4f8d80SVincenzo Maffione int fd; /* "/dev/netmap", -1 if not open */ 1995c4f8d80SVincenzo Maffione struct netmap_if *nifp; /* pointer to the netmap_if */ 2005c4f8d80SVincenzo Maffione uint16_t first_tx_ring; 2015c4f8d80SVincenzo Maffione uint16_t last_tx_ring; 2025c4f8d80SVincenzo Maffione uint16_t first_rx_ring; 2035c4f8d80SVincenzo Maffione uint16_t last_rx_ring; 2045c4f8d80SVincenzo Maffione uint16_t cur_tx_ring; /* used by nmport_inject */ 2055c4f8d80SVincenzo Maffione uint16_t cur_rx_ring; 2065c4f8d80SVincenzo Maffione 2075c4f8d80SVincenzo Maffione /* LIFO list of cleanup functions (used internally) */ 2085c4f8d80SVincenzo Maffione struct nmport_cleanup_d *clist; 2095c4f8d80SVincenzo Maffione }; 2105c4f8d80SVincenzo Maffione 2115c4f8d80SVincenzo Maffione /* nmport_open - opens a port from a portspec 2125c4f8d80SVincenzo Maffione * @portspec the port opening specification 2135c4f8d80SVincenzo Maffione * 2145c4f8d80SVincenzo Maffione * If successful, the function returns a new nmport_d describing a netmap 2155c4f8d80SVincenzo Maffione * port, opened according to the port specification, ready to be used for rx 2165c4f8d80SVincenzo Maffione * and/or tx. 2175c4f8d80SVincenzo Maffione * 2185c4f8d80SVincenzo Maffione * The rings available for tx are in the [first_tx_ring, last_tx_ring] 2195c4f8d80SVincenzo Maffione * interval, and similarly for rx. One or both intervals may be empty. 2205c4f8d80SVincenzo Maffione * 2215c4f8d80SVincenzo Maffione * When done using it, the nmport_d descriptor must be closed using 2225c4f8d80SVincenzo Maffione * nmport_close(). 2235c4f8d80SVincenzo Maffione * 2245c4f8d80SVincenzo Maffione * In case of error, NULL is returned, errno is set to some error, and an 2255c4f8d80SVincenzo Maffione * error message is sent through the error() method of the current context. 2265c4f8d80SVincenzo Maffione */ 2275c4f8d80SVincenzo Maffione struct nmport_d * nmport_open(const char *portspec); 2285c4f8d80SVincenzo Maffione 2295c4f8d80SVincenzo Maffione /* nport_close - close a netmap port 2305c4f8d80SVincenzo Maffione * @d the port we want to close 2315c4f8d80SVincenzo Maffione * 2325c4f8d80SVincenzo Maffione * Undoes the actions performed by the nmport_open that created d, then 2335c4f8d80SVincenzo Maffione * frees the descriptor. 2345c4f8d80SVincenzo Maffione */ 2355c4f8d80SVincenzo Maffione void nmport_close(struct nmport_d *d); 2365c4f8d80SVincenzo Maffione 2375c4f8d80SVincenzo Maffione /* nmport_inject - sends a packet 2385c4f8d80SVincenzo Maffione * @d the port through which we want to send 2395c4f8d80SVincenzo Maffione * @buf base address of the packet 2405c4f8d80SVincenzo Maffione * @size its size in bytes 2415c4f8d80SVincenzo Maffione * 2425c4f8d80SVincenzo Maffione * Sends a packet using the cur_tx_ring and updates the index 2435c4f8d80SVincenzo Maffione * to use all available tx rings in turn. Note: the packet is copied. 2445c4f8d80SVincenzo Maffione * 2455c4f8d80SVincenzo Maffione * Returns 0 on success an -1 on error. 2465c4f8d80SVincenzo Maffione */ 2475c4f8d80SVincenzo Maffione int nmport_inject(struct nmport_d *d, const void *buf, size_t size); 2485c4f8d80SVincenzo Maffione 2495c4f8d80SVincenzo Maffione /* 2505c4f8d80SVincenzo Maffione * the functions below can be used to split the functionality of 2515c4f8d80SVincenzo Maffione * nmport_open when special features (e.g., extra buffers) are needed 2525c4f8d80SVincenzo Maffione * 2535c4f8d80SVincenzo Maffione * The relation among the functions is as follows: 2545c4f8d80SVincenzo Maffione * 2555c4f8d80SVincenzo Maffione * |nmport_new 2565c4f8d80SVincenzo Maffione * |nmport_prepare = | 2575c4f8d80SVincenzo Maffione * | |nmport_parse 2585c4f8d80SVincenzo Maffione * nmport_open =| 2595c4f8d80SVincenzo Maffione * | |nmport_register 2605c4f8d80SVincenzo Maffione * |nmport_open_desc =| 2615c4f8d80SVincenzo Maffione * |nmport_mmap 2625c4f8d80SVincenzo Maffione * 2635c4f8d80SVincenzo Maffione */ 2645c4f8d80SVincenzo Maffione 2655c4f8d80SVincenzo Maffione /* nmport_new - create a new nmport_d 2665c4f8d80SVincenzo Maffione * 2675c4f8d80SVincenzo Maffione * Creates a new nmport_d using the malloc() method of the current default 2685c4f8d80SVincenzo Maffione * context. Returns NULL on error, setting errno to an error value. 2695c4f8d80SVincenzo Maffione */ 2705c4f8d80SVincenzo Maffione struct nmport_d *nmport_new(void); 2715c4f8d80SVincenzo Maffione 2725c4f8d80SVincenzo Maffione /* nmport_parse - fills the nmport_d netmap-register request 2735c4f8d80SVincenzo Maffione * @d the nmport to be filled 2745c4f8d80SVincenzo Maffione * @portspec the port opening specification 2755c4f8d80SVincenzo Maffione * 2765c4f8d80SVincenzo Maffione * This function parses the portspec and initizalizes the @d->hdr and @d->reg 2775c4f8d80SVincenzo Maffione * fields. It may need to allocate a list of options. If an extmem option is 2785c4f8d80SVincenzo Maffione * found, it may also mmap() the corresponding file. 2795c4f8d80SVincenzo Maffione * 2805c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 2815c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 2825c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 2835c4f8d80SVincenzo Maffione */ 2845c4f8d80SVincenzo Maffione int nmport_parse(struct nmport_d *d, const char *portspec); 2855c4f8d80SVincenzo Maffione 2865c4f8d80SVincenzo Maffione /* nmport_register - registers the port with netmap 2875c4f8d80SVincenzo Maffione * @d the nmport to be registered 2885c4f8d80SVincenzo Maffione * 2895c4f8d80SVincenzo Maffione * This function obtains a netmap file descriptor and registers the port with 2905c4f8d80SVincenzo Maffione * netmap. The @d->hdr and @d->reg data structures must have been previously 2915c4f8d80SVincenzo Maffione * initialized (via nmport_parse() or otherwise). 2925c4f8d80SVincenzo Maffione * 2935c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 2945c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 2955c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 2965c4f8d80SVincenzo Maffione */ 2975c4f8d80SVincenzo Maffione int nmport_register(struct nmport_d *); 2985c4f8d80SVincenzo Maffione 2995c4f8d80SVincenzo Maffione /* nmport_mmap - maps the port resources into the process memory 3005c4f8d80SVincenzo Maffione * @d the nmport to be mapped 3015c4f8d80SVincenzo Maffione * 3025c4f8d80SVincenzo Maffione * The port must have been previously been registered using nmport_register. 3035c4f8d80SVincenzo Maffione * 3045c4f8d80SVincenzo Maffione * Note that if extmem is used (either via an option or by calling an 3055c4f8d80SVincenzo Maffione * nmport_extmem_* function before nmport_register()), no new mmap() is issued. 3065c4f8d80SVincenzo Maffione * 3075c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 3085c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 3095c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 3105c4f8d80SVincenzo Maffione */ 3115c4f8d80SVincenzo Maffione int nmport_mmap(struct nmport_d *); 3125c4f8d80SVincenzo Maffione 3135c4f8d80SVincenzo Maffione /* the following functions undo the actions of nmport_new(), nmport_parse(), 3145c4f8d80SVincenzo Maffione * nmport_register() and nmport_mmap(), respectively. 3155c4f8d80SVincenzo Maffione */ 3165c4f8d80SVincenzo Maffione void nmport_delete(struct nmport_d *); 3175c4f8d80SVincenzo Maffione void nmport_undo_parse(struct nmport_d *); 3185c4f8d80SVincenzo Maffione void nmport_undo_register(struct nmport_d *); 3195c4f8d80SVincenzo Maffione void nmport_undo_mmap(struct nmport_d *); 3205c4f8d80SVincenzo Maffione 3215c4f8d80SVincenzo Maffione /* nmport_prepare - create a port descriptor, but do not open it 3225c4f8d80SVincenzo Maffione * @portspec the port opening specification 3235c4f8d80SVincenzo Maffione * 3245c4f8d80SVincenzo Maffione * This functions creates a new nmport_d and initializes it according to 3255c4f8d80SVincenzo Maffione * @portspec. It is equivalent to nmport_new() followed by nmport_parse(). 3265c4f8d80SVincenzo Maffione * 3275c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 3285c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 3295c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 3305c4f8d80SVincenzo Maffione */ 3315c4f8d80SVincenzo Maffione struct nmport_d *nmport_prepare(const char *portspec); 3325c4f8d80SVincenzo Maffione 3335c4f8d80SVincenzo Maffione /* nmport_open_desc - open an initialized port descriptor 3345c4f8d80SVincenzo Maffione * @d the descriptor we want to open 3355c4f8d80SVincenzo Maffione * 3365c4f8d80SVincenzo Maffione * Registers the port with netmap and maps the rings and buffers into the 3375c4f8d80SVincenzo Maffione * process memory. It is equivalent to nmport_register() followed by 3385c4f8d80SVincenzo Maffione * nmport_mmap(). 3395c4f8d80SVincenzo Maffione * 3405c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 3415c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 3425c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 3435c4f8d80SVincenzo Maffione */ 3445c4f8d80SVincenzo Maffione int nmport_open_desc(struct nmport_d *d); 3455c4f8d80SVincenzo Maffione 3465c4f8d80SVincenzo Maffione /* the following functions undo the actions of nmport_prepare() 3475c4f8d80SVincenzo Maffione * and nmport_open_desc(), respectively. 3485c4f8d80SVincenzo Maffione */ 3495c4f8d80SVincenzo Maffione void nmport_undo_prepare(struct nmport_d *); 3505c4f8d80SVincenzo Maffione void nmport_undo_open_desc(struct nmport_d *); 3515c4f8d80SVincenzo Maffione 3525c4f8d80SVincenzo Maffione /* nmport_clone - copy an nmport_d 3535c4f8d80SVincenzo Maffione * @d the nmport_d we want to copy 3545c4f8d80SVincenzo Maffione * 3555c4f8d80SVincenzo Maffione * Copying an nmport_d by hand should be avoided, since adjustments are needed 3565c4f8d80SVincenzo Maffione * and some part of the state cannot be easily duplicated. This function 3575c4f8d80SVincenzo Maffione * creates a copy of @d in a safe way. The returned nmport_d contains 3585c4f8d80SVincenzo Maffione * nmreq_header and nmreq_register structures equivalent to those contained in 3595c4f8d80SVincenzo Maffione * @d, except for the option list, which is ignored. The returned nmport_d is 3605c4f8d80SVincenzo Maffione * already nmport_prepare()d, but it must still be nmport_open_desc()ed. The 3615c4f8d80SVincenzo Maffione * new nmport_d uses the same nmctx as @d. 3625c4f8d80SVincenzo Maffione * 3635c4f8d80SVincenzo Maffione * If extmem was used for @d, then @d cannot be nmport_clone()d until it has 3645c4f8d80SVincenzo Maffione * been nmport_register()ed. 3655c4f8d80SVincenzo Maffione * 3665c4f8d80SVincenzo Maffione * In case of error, the function returns NULL, sets errno to an error value 3675c4f8d80SVincenzo Maffione * and sends an error message to the nmctx error() method. 3685c4f8d80SVincenzo Maffione */ 3695c4f8d80SVincenzo Maffione struct nmport_d *nmport_clone(struct nmport_d *); 3705c4f8d80SVincenzo Maffione 3715c4f8d80SVincenzo Maffione /* nmport_extmem - use extmem for this port 3725c4f8d80SVincenzo Maffione * @d the port we want to use the extmem for 3735c4f8d80SVincenzo Maffione * @base the base address of the extmem region 3745c4f8d80SVincenzo Maffione * @size the size in bytes of the extmem region 3755c4f8d80SVincenzo Maffione * 3765c4f8d80SVincenzo Maffione * the memory that contains the netmap ifs, rings and buffers is usually 3775c4f8d80SVincenzo Maffione * allocated by netmap and later mmap()ed by the applications. It is sometimes 3785c4f8d80SVincenzo Maffione * useful to reverse this process, by having the applications allocate some 3795c4f8d80SVincenzo Maffione * memory (through mmap() or otherwise) and then let netmap use it. The extmem 3805c4f8d80SVincenzo Maffione * option can be used to implement this latter strategy. The option can be 3815c4f8d80SVincenzo Maffione * passed through the portspec using the '@extmem:...' syntax, or 3825c4f8d80SVincenzo Maffione * programmatically by calling nmport_extmem() or nmport_extmem_from_file() 3835c4f8d80SVincenzo Maffione * between nmport_parse() and nmport_register() (or between nmport_prepare() 3845c4f8d80SVincenzo Maffione * and nmport_open_desc()). 3855c4f8d80SVincenzo Maffione * 3865c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 3875c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 3885c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 3895c4f8d80SVincenzo Maffione */ 3905c4f8d80SVincenzo Maffione int nmport_extmem(struct nmport_d *d, void *base, size_t size); 3915c4f8d80SVincenzo Maffione 3925c4f8d80SVincenzo Maffione /* nmport_extmem_from_file - use the extmem obtained by mapping a file 3935c4f8d80SVincenzo Maffione * @d the port we want to use the extmem for 3945c4f8d80SVincenzo Maffione * @fname path of the file we want to map 3955c4f8d80SVincenzo Maffione * 3965c4f8d80SVincenzo Maffione * This works like nmport_extmem, but the extmem memory is obtained by 3975c4f8d80SVincenzo Maffione * mmap()ping @fname. nmport_close() will also automatically munmap() the file. 3985c4f8d80SVincenzo Maffione * 3995c4f8d80SVincenzo Maffione * It returns 0 on success. On failure it returns -1, sets errno to an error 4005c4f8d80SVincenzo Maffione * value and sends an error message to the error() method of the context used 4015c4f8d80SVincenzo Maffione * when @d was created. Moreover, *@d is left unchanged. 4025c4f8d80SVincenzo Maffione */ 4035c4f8d80SVincenzo Maffione int nmport_extmem_from_file(struct nmport_d *d, const char *fname); 4045c4f8d80SVincenzo Maffione 4055c4f8d80SVincenzo Maffione /* nmport_extmem_getinfo - opbtai a pointer to the extmem configuration 4065c4f8d80SVincenzo Maffione * @d the port we want to obtain the pointer from 4075c4f8d80SVincenzo Maffione * 4085c4f8d80SVincenzo Maffione * Returns a pointer to the nmreq_pools_info structure containing the 4095c4f8d80SVincenzo Maffione * configuration of the extmem attached to port @d, or NULL if no extmem 4105c4f8d80SVincenzo Maffione * is attached. This can be used to set the desired configuration before 4115c4f8d80SVincenzo Maffione * registering the port, or to read the actual configuration after 4125c4f8d80SVincenzo Maffione * registration. 4135c4f8d80SVincenzo Maffione */ 4145c4f8d80SVincenzo Maffione struct nmreq_pools_info* nmport_extmem_getinfo(struct nmport_d *d); 4155c4f8d80SVincenzo Maffione 4165c4f8d80SVincenzo Maffione 417f8113f0aSVincenzo Maffione /* nmport_offset - use offsets for this port 418f8113f0aSVincenzo Maffione * @initial the initial offset for all the slots 419f8113f0aSVincenzo Maffione * @maxoff the maximum offset 420f8113f0aSVincenzo Maffione * @bits the number of bits of slot->ptr to use for the offsets 421*45c67e8fSVincenzo Maffione * @mingap the minimum gap between offsets (in shared buffers) 422f8113f0aSVincenzo Maffione * 423f8113f0aSVincenzo Maffione * With this option the lower @bits bits of the ptr field in the netmap_slot 424f8113f0aSVincenzo Maffione * can be used to specify an offset into the buffer. All offsets will be set 425f8113f0aSVincenzo Maffione * to the @initial value by netmap. 426f8113f0aSVincenzo Maffione * 427f8113f0aSVincenzo Maffione * The offset field can be read and updated using the bitmask found in 428f8113f0aSVincenzo Maffione * ring->offset_mask after a successful register. netmap_user.h contains 429f8113f0aSVincenzo Maffione * some helper macros (NETMAP_ROFFSET, NETMAP_WOFFSET and NETMAP_BUF_OFFSET). 430f8113f0aSVincenzo Maffione * 431f8113f0aSVincenzo Maffione * For RX rings, the user writes the offset o in an empty slot before passing 432f8113f0aSVincenzo Maffione * it to netmap; then, netmap will write the incoming packet at an offset o' >= 433f8113f0aSVincenzo Maffione * o in the buffer. o' may be larger than o because of, e.g., alignment 434f8113f0aSVincenzo Maffione * constrains. If o' > o netmap will also update the offset field in the slot. 435f8113f0aSVincenzo Maffione * Note that large offsets may cause the port to split the packet over several 436f8113f0aSVincenzo Maffione * slots, setting the NS_MOREFRAG flag accordingly. 437f8113f0aSVincenzo Maffione * 438f8113f0aSVincenzo Maffione * For TX rings, the user may prepare the packet to send at an offset o into 439f8113f0aSVincenzo Maffione * the buffer and write o in the offset field. Netmap will send the packets 440f8113f0aSVincenzo Maffione * starting o bytes in the buffer. Note that the address of the packet must 441f8113f0aSVincenzo Maffione * comply with any alignment constraints that the port may have, or the result 442f8113f0aSVincenzo Maffione * will be undefined. The user may read the alignment constraint in the new 443*45c67e8fSVincenzo Maffione * ring->buf_align field. It is also possible that empty slots already come 444f8113f0aSVincenzo Maffione * with a non-zero offset o specified in the offset field. In this case, the 445f8113f0aSVincenzo Maffione * user will have to write the packet at an offset o' >= o. 446f8113f0aSVincenzo Maffione * 447f8113f0aSVincenzo Maffione * The user must also declare the @maxoff offset that she is going to use. Any 448f8113f0aSVincenzo Maffione * offset larger than this will be truncated. 449f8113f0aSVincenzo Maffione * 450f8113f0aSVincenzo Maffione * The user may also declare a @mingap (ignored if zero) if she plans to use 451f8113f0aSVincenzo Maffione * offsets to share the same buffer among several slots. Netmap will guarantee 452f8113f0aSVincenzo Maffione * that it will never write more than @mingap bytes for each slot, irrespective 453f8113f0aSVincenzo Maffione * of the buffer length. 454f8113f0aSVincenzo Maffione */ 455f8113f0aSVincenzo Maffione int nmport_offset(struct nmport_d *d, uint64_t initial, uint64_t maxoff, 456f8113f0aSVincenzo Maffione uint64_t bits, uint64_t mingap); 457f8113f0aSVincenzo Maffione 4585c4f8d80SVincenzo Maffione /* enable/disable options 4595c4f8d80SVincenzo Maffione * 4605c4f8d80SVincenzo Maffione * These functions can be used to disable options that the application cannot 4615c4f8d80SVincenzo Maffione * or doesn't want to handle, or to enable options that require special support 4625c4f8d80SVincenzo Maffione * from the application and are, therefore, disabled by default. Disabled 4635c4f8d80SVincenzo Maffione * options will cause an error if encountered during option parsing. 4645c4f8d80SVincenzo Maffione * 4655c4f8d80SVincenzo Maffione * If the option is unknown, nmport_disable_option is a NOP, while 4665c4f8d80SVincenzo Maffione * nmport_enable_option returns -1 and sets errno to EOPNOTSUPP. 4675c4f8d80SVincenzo Maffione * 4685c4f8d80SVincenzo Maffione * These functions are not threadsafe and are meant to be used at the beginning 4695c4f8d80SVincenzo Maffione * of the program. 4705c4f8d80SVincenzo Maffione */ 4715c4f8d80SVincenzo Maffione void nmport_disable_option(const char *opt); 4725c4f8d80SVincenzo Maffione int nmport_enable_option(const char *opt); 4735c4f8d80SVincenzo Maffione 4745c4f8d80SVincenzo Maffione /* nmreq manipulation 4755c4f8d80SVincenzo Maffione * 4765c4f8d80SVincenzo Maffione * nmreq_header_init - initialize an nmreq_header 4775c4f8d80SVincenzo Maffione * @hdr the nmreq_header to initialize 4785c4f8d80SVincenzo Maffione * @reqtype the kind of netmap request 4795c4f8d80SVincenzo Maffione * @body the body of the request 4805c4f8d80SVincenzo Maffione * 4815c4f8d80SVincenzo Maffione * Initialize the nr_version, nr_reqtype and nr_body fields of *@hdr. 4825c4f8d80SVincenzo Maffione * The other fields are set to zero. 4835c4f8d80SVincenzo Maffione */ 4845c4f8d80SVincenzo Maffione void nmreq_header_init(struct nmreq_header *hdr, uint16_t reqtype, void *body); 4855c4f8d80SVincenzo Maffione 4865c4f8d80SVincenzo Maffione /* 4875c4f8d80SVincenzo Maffione * These functions allow for finer grained parsing of portspecs. They are used 4885c4f8d80SVincenzo Maffione * internally by nmport_parse(). 4895c4f8d80SVincenzo Maffione */ 4905c4f8d80SVincenzo Maffione 4915c4f8d80SVincenzo Maffione /* nmreq_header_decode - initialize an nmreq_header 4925c4f8d80SVincenzo Maffione * @ppspec: (in/out) pointer to a pointer to the portspec 4935c4f8d80SVincenzo Maffione * @hdr: pointer to the nmreq_header to be initialized 4945c4f8d80SVincenzo Maffione * @ctx: pointer to the nmctx to use (for errors) 4955c4f8d80SVincenzo Maffione * 4965c4f8d80SVincenzo Maffione * This function fills the @hdr the nr_name field with the port name extracted 4975c4f8d80SVincenzo Maffione * from *@pifname. The other fields of *@hdr are unchanged. The @pifname is 4985c4f8d80SVincenzo Maffione * updated to point at the first char past the port name. 4995c4f8d80SVincenzo Maffione * 5005c4f8d80SVincenzo Maffione * Returns 0 on success. In case of error, -1 is returned with errno set to 5015c4f8d80SVincenzo Maffione * EINVAL, @pifname is unchanged, *@hdr is also unchanged, and an error message 5025c4f8d80SVincenzo Maffione * is sent through @ctx->error(). 5035c4f8d80SVincenzo Maffione */ 5045c4f8d80SVincenzo Maffione int nmreq_header_decode(const char **ppspec, struct nmreq_header *hdr, 5055c4f8d80SVincenzo Maffione struct nmctx *ctx); 5065c4f8d80SVincenzo Maffione 5075c4f8d80SVincenzo Maffione /* nmreq_regiter_decode - initialize an nmreq_register 5085c4f8d80SVincenzo Maffione * @pmode: (in/out) pointer to a pointer to an opening mode 5095c4f8d80SVincenzo Maffione * @reg: pointer to the nmreq_register to be initialized 5105c4f8d80SVincenzo Maffione * @ctx: pointer to the nmctx to use (for errors) 5115c4f8d80SVincenzo Maffione * 5125c4f8d80SVincenzo Maffione * This function fills the nr_mode, nr_ringid, nr_flags and nr_mem_id fields of 5135c4f8d80SVincenzo Maffione * the structure pointed by @reg, according to the opening mode specified by 5145c4f8d80SVincenzo Maffione * *@pmode. The other fields of *@reg are unchanged. The @pmode is updated to 5155c4f8d80SVincenzo Maffione * point at the first char past the opening mode. 5165c4f8d80SVincenzo Maffione * 5175c4f8d80SVincenzo Maffione * If a '@' is encountered followed by something which is not a number, parsing 5185c4f8d80SVincenzo Maffione * stops (without error) and @pmode is left pointing at the '@' char. The 5195c4f8d80SVincenzo Maffione * nr_mode, nr_ringid and nr_flags fields are still updated, but nr_mem_id is 5205c4f8d80SVincenzo Maffione * not touched and the interpretation of the '@' field is left to the caller. 5215c4f8d80SVincenzo Maffione * 5225c4f8d80SVincenzo Maffione * Returns 0 on success. In case of error, -1 is returned with errno set to 5235c4f8d80SVincenzo Maffione * EINVAL, @pmode is unchanged, *@reg is also unchanged, and an error message 5245c4f8d80SVincenzo Maffione * is sent through @ctx->error(). 5255c4f8d80SVincenzo Maffione */ 5265c4f8d80SVincenzo Maffione int nmreq_register_decode(const char **pmode, struct nmreq_register *reg, 5275c4f8d80SVincenzo Maffione struct nmctx *ctx); 5285c4f8d80SVincenzo Maffione 5295c4f8d80SVincenzo Maffione /* nmreq_options_decode - parse the "options" part of the portspec 5305c4f8d80SVincenzo Maffione * @opt: pointer to the option list 5315c4f8d80SVincenzo Maffione * @parsers: list of option parsers 5325c4f8d80SVincenzo Maffione * @token: token to pass to each parser 5335c4f8d80SVincenzo Maffione * @ctx: pointer to the nmctx to use (for errors and malloc/free) 5345c4f8d80SVincenzo Maffione * 5355c4f8d80SVincenzo Maffione * This function parses each option in @opt. Each option is matched (based on 5365c4f8d80SVincenzo Maffione * the "option" prefix) to a corresponding parser in @parsers. The function 5375c4f8d80SVincenzo Maffione * checks that the syntax is appropriate for the parser and it assigns all the 5385c4f8d80SVincenzo Maffione * keys mentioned in the option. It then passes control to the parser, to 5395c4f8d80SVincenzo Maffione * interpret the keys values. 5405c4f8d80SVincenzo Maffione * 5415c4f8d80SVincenzo Maffione * Returns 0 on success. In case of error, -1 is returned, errno is set to an 5425c4f8d80SVincenzo Maffione * error value and a message is sent to @ctx->error(). The effects of partially 5435c4f8d80SVincenzo Maffione * interpreted options may not be undone. 5445c4f8d80SVincenzo Maffione */ 5455c4f8d80SVincenzo Maffione struct nmreq_opt_parser; 5465c4f8d80SVincenzo Maffione int nmreq_options_decode(const char *opt, struct nmreq_opt_parser *parsers, 5475c4f8d80SVincenzo Maffione void *token, struct nmctx *ctx); 5485c4f8d80SVincenzo Maffione 5495c4f8d80SVincenzo Maffione struct nmreq_parse_ctx; 5505c4f8d80SVincenzo Maffione /* type of the option-parsers callbacks */ 5515c4f8d80SVincenzo Maffione typedef int (*nmreq_opt_parser_cb)(struct nmreq_parse_ctx *); 5525c4f8d80SVincenzo Maffione 5535c4f8d80SVincenzo Maffione #define NMREQ_OPT_MAXKEYS 16 /* max nr of recognized keys per option */ 5545c4f8d80SVincenzo Maffione 5555c4f8d80SVincenzo Maffione /* struct nmreq_opt_key - describes an option key */ 5565c4f8d80SVincenzo Maffione struct nmreq_opt_key { 5575c4f8d80SVincenzo Maffione const char *key; /* the key name */ 5585c4f8d80SVincenzo Maffione int id; /* its position in the parse context */ 5595c4f8d80SVincenzo Maffione unsigned int flags; 5605c4f8d80SVincenzo Maffione #define NMREQ_OPTK_ALLOWEMPTY (1U << 0) /* =value may be omitted */ 5615c4f8d80SVincenzo Maffione #define NMREQ_OPTK_MUSTSET (1U << 1) /* the key is mandatory */ 5625c4f8d80SVincenzo Maffione #define NMREQ_OPTK_DEFAULT (1U << 2) /* this is the default key */ 5635c4f8d80SVincenzo Maffione }; 5645c4f8d80SVincenzo Maffione 5655c4f8d80SVincenzo Maffione /* struct nmreq_opt_parser - describes an option parser */ 5665c4f8d80SVincenzo Maffione struct nmreq_opt_parser { 5675c4f8d80SVincenzo Maffione const char *prefix; /* matches one option prefix */ 5685c4f8d80SVincenzo Maffione nmreq_opt_parser_cb parse; /* the parse callback */ 5695c4f8d80SVincenzo Maffione int default_key; /* which option is the default if the 5705c4f8d80SVincenzo Maffione parser is multi-key (-1 if none) */ 5715c4f8d80SVincenzo Maffione int nr_keys; 5725c4f8d80SVincenzo Maffione unsigned int flags; 5735c4f8d80SVincenzo Maffione #define NMREQ_OPTF_DISABLED (1U << 0) 5745c4f8d80SVincenzo Maffione #define NMREQ_OPTF_ALLOWEMPTY (1U << 1) /* =value can be omitted */ 5755c4f8d80SVincenzo Maffione 5765c4f8d80SVincenzo Maffione struct nmreq_opt_parser *next; /* list of options */ 5775c4f8d80SVincenzo Maffione 5785c4f8d80SVincenzo Maffione /* recognized keys */ 5795c4f8d80SVincenzo Maffione struct nmreq_opt_key keys[NMREQ_OPT_MAXKEYS]; 5805c4f8d80SVincenzo Maffione } __attribute__((aligned(16))); 5815c4f8d80SVincenzo Maffione 5825c4f8d80SVincenzo Maffione /* struct nmreq_parse_ctx - the parse context received by the parse callback */ 5835c4f8d80SVincenzo Maffione struct nmreq_parse_ctx { 5845c4f8d80SVincenzo Maffione struct nmctx *ctx; /* the nmctx for errors and malloc/free */ 5855c4f8d80SVincenzo Maffione void *token; /* the token passed to nmreq_options_parse */ 5865c4f8d80SVincenzo Maffione 5875c4f8d80SVincenzo Maffione /* the value (i.e., the part after the = sign) of each recognized key 5885c4f8d80SVincenzo Maffione * is assigned to the corresponding entry in this array, based on the 5895c4f8d80SVincenzo Maffione * key id. Unassigned keys are left at NULL. 5905c4f8d80SVincenzo Maffione */ 5915c4f8d80SVincenzo Maffione const char *keys[NMREQ_OPT_MAXKEYS]; 5925c4f8d80SVincenzo Maffione }; 5935c4f8d80SVincenzo Maffione 5945c4f8d80SVincenzo Maffione /* nmreq_get_mem_id - get the mem_id of the given port 5955c4f8d80SVincenzo Maffione * @portname pointer to a pointer to the portname 5965c4f8d80SVincenzo Maffione * @ctx pointer to the nmctx to use (for errors) 5975c4f8d80SVincenzo Maffione * 5985c4f8d80SVincenzo Maffione * *@portname must point to a substem:vpname porname, possibly followed by 5995c4f8d80SVincenzo Maffione * something else. 6005c4f8d80SVincenzo Maffione * 6015c4f8d80SVincenzo Maffione * If successful, returns the mem_id of *@portname and moves @portname past the 6025c4f8d80SVincenzo Maffione * subsystem:vpname part of the input. In case of error it returns -1, sets 6035c4f8d80SVincenzo Maffione * errno to an error value and sends an error message to ctx->error(). 6045c4f8d80SVincenzo Maffione */ 6055c4f8d80SVincenzo Maffione int32_t nmreq_get_mem_id(const char **portname, struct nmctx *ctx); 6065c4f8d80SVincenzo Maffione 6075c4f8d80SVincenzo Maffione /* option list manipulation */ 6085c4f8d80SVincenzo Maffione void nmreq_push_option(struct nmreq_header *, struct nmreq_option *); 6095c4f8d80SVincenzo Maffione void nmreq_remove_option(struct nmreq_header *, struct nmreq_option *); 6105c4f8d80SVincenzo Maffione struct nmreq_option *nmreq_find_option(struct nmreq_header *, uint32_t); 6115c4f8d80SVincenzo Maffione void nmreq_free_options(struct nmreq_header *); 6125c4f8d80SVincenzo Maffione const char* nmreq_option_name(uint32_t); 6135c4f8d80SVincenzo Maffione #define nmreq_foreach_option(h_, o_) \ 61492c5d82cSVincenzo Maffione for ((o_) = (struct nmreq_option *)((uintptr_t)((h_)->nr_options));\ 6155c4f8d80SVincenzo Maffione (o_) != NULL;\ 61692c5d82cSVincenzo Maffione (o_) = (struct nmreq_option *)((uintptr_t)((o_)->nro_next))) 6175c4f8d80SVincenzo Maffione 6185c4f8d80SVincenzo Maffione /* nmctx manipulation */ 6195c4f8d80SVincenzo Maffione 6205c4f8d80SVincenzo Maffione /* the nmctx serves a few purposes: 6215c4f8d80SVincenzo Maffione * 6225c4f8d80SVincenzo Maffione * - maintain a list of all memory regions open by the program, so that two 6235c4f8d80SVincenzo Maffione * ports that are using the same region (as identified by the mem_id) will 6245c4f8d80SVincenzo Maffione * point to the same nmem_d instance. 6255c4f8d80SVincenzo Maffione * 6265c4f8d80SVincenzo Maffione * - allow the user to specify how to lock accesses to the above list, if 6275c4f8d80SVincenzo Maffione * needed (lock() callback) 6285c4f8d80SVincenzo Maffione * 6295c4f8d80SVincenzo Maffione * - allow the user to specify how error messages should be delivered (error() 6305c4f8d80SVincenzo Maffione * callback) 6315c4f8d80SVincenzo Maffione * 6325c4f8d80SVincenzo Maffione * - select the verbosity of the library (verbose field); if verbose==0, no 6335c4f8d80SVincenzo Maffione * errors are sent to the error() callback 6345c4f8d80SVincenzo Maffione * 6355c4f8d80SVincenzo Maffione * - allow the user to override the malloc/free functions used by the library 6365c4f8d80SVincenzo Maffione * (malloc() and free() callbacks) 6375c4f8d80SVincenzo Maffione * 6385c4f8d80SVincenzo Maffione */ 6395c4f8d80SVincenzo Maffione typedef void (*nmctx_error_cb)(struct nmctx *, const char *); 6405c4f8d80SVincenzo Maffione typedef void *(*nmctx_malloc_cb)(struct nmctx *,size_t); 6415c4f8d80SVincenzo Maffione typedef void (*nmctx_free_cb)(struct nmctx *,void *); 6425c4f8d80SVincenzo Maffione typedef void (*nmctx_lock_cb)(struct nmctx *, int); 6435c4f8d80SVincenzo Maffione 6445c4f8d80SVincenzo Maffione struct nmctx { 6455c4f8d80SVincenzo Maffione int verbose; 6465c4f8d80SVincenzo Maffione nmctx_error_cb error; 6475c4f8d80SVincenzo Maffione nmctx_malloc_cb malloc; 6485c4f8d80SVincenzo Maffione nmctx_free_cb free; 6495c4f8d80SVincenzo Maffione nmctx_lock_cb lock; 6505c4f8d80SVincenzo Maffione 6515c4f8d80SVincenzo Maffione struct nmem_d *mem_descs; 6525c4f8d80SVincenzo Maffione }; 6535c4f8d80SVincenzo Maffione 6545c4f8d80SVincenzo Maffione /* nmctx_get - obtain a pointer to the current default context */ 6555c4f8d80SVincenzo Maffione struct nmctx *nmctx_get(void); 6565c4f8d80SVincenzo Maffione 6575c4f8d80SVincenzo Maffione /* nmctx_set_default - change the default context 6585c4f8d80SVincenzo Maffione * @ctx pointer to the new context 6595c4f8d80SVincenzo Maffione * 6605c4f8d80SVincenzo Maffione * Returns a pointer to the previous default context. 6615c4f8d80SVincenzo Maffione */ 6625c4f8d80SVincenzo Maffione struct nmctx *nmctx_set_default(struct nmctx *ctx); 6635c4f8d80SVincenzo Maffione 6645c4f8d80SVincenzo Maffione /* internal functions and data structures */ 6655c4f8d80SVincenzo Maffione 6665c4f8d80SVincenzo Maffione /* struct nmem_d - describes a memory region currently used */ 6675c4f8d80SVincenzo Maffione struct nmem_d { 6685c4f8d80SVincenzo Maffione uint16_t mem_id; /* the region netmap identifier */ 6695c4f8d80SVincenzo Maffione int refcount; /* how many nmport_d's point here */ 6705c4f8d80SVincenzo Maffione void *mem; /* memory region base address */ 6715c4f8d80SVincenzo Maffione size_t size; /* memory region size */ 6725c4f8d80SVincenzo Maffione int is_extmem; /* was it obtained via extmem? */ 6735c4f8d80SVincenzo Maffione 6745c4f8d80SVincenzo Maffione /* pointers for the circular list implementation. 6755c4f8d80SVincenzo Maffione * The list head is the mem_descs filed in the nmctx 6765c4f8d80SVincenzo Maffione */ 6775c4f8d80SVincenzo Maffione struct nmem_d *next; 6785c4f8d80SVincenzo Maffione struct nmem_d *prev; 6795c4f8d80SVincenzo Maffione }; 6805c4f8d80SVincenzo Maffione 6815c4f8d80SVincenzo Maffione /* a trick to force the inclusion of libpthread only if requested. If 6825c4f8d80SVincenzo Maffione * LIBNETMAP_NOTHREADSAFE is defined, no pthread symbol is imported. 6835c4f8d80SVincenzo Maffione * 6845c4f8d80SVincenzo Maffione * There is no need to actually call this function: the ((used)) attribute is 6855c4f8d80SVincenzo Maffione * sufficient to include it in the image. 6865c4f8d80SVincenzo Maffione */ 6875c4f8d80SVincenzo Maffione static __attribute__((used)) void libnetmap_init(void) 6885c4f8d80SVincenzo Maffione { 6895c4f8d80SVincenzo Maffione #ifndef LIBNETMAP_NOTHREADSAFE 6905c4f8d80SVincenzo Maffione extern int nmctx_threadsafe; 6915c4f8d80SVincenzo Maffione /* dummy assignment to link-in the nmctx-pthread.o object. The proper 6925c4f8d80SVincenzo Maffione * inizialization is performed only once in the library constructor 6935c4f8d80SVincenzo Maffione * defined there. 6945c4f8d80SVincenzo Maffione */ 6955c4f8d80SVincenzo Maffione nmctx_threadsafe = 1; 6965c4f8d80SVincenzo Maffione #endif /* LIBNETMAP_NOTHREADSAFE */ 6975c4f8d80SVincenzo Maffione } 6985c4f8d80SVincenzo Maffione 6995c4f8d80SVincenzo Maffione /* nmctx_set_threadsafe - install a threadsafe default context 7005c4f8d80SVincenzo Maffione * 7015c4f8d80SVincenzo Maffione * called by the constructor in nmctx-pthread.o to initialize a lock and install 7025c4f8d80SVincenzo Maffione * the lock() callback in the default context. 7035c4f8d80SVincenzo Maffione */ 7045c4f8d80SVincenzo Maffione void nmctx_set_threadsafe(void); 7055c4f8d80SVincenzo Maffione 7065c4f8d80SVincenzo Maffione /* nmctx_ferror - format and send an error message */ 7075c4f8d80SVincenzo Maffione void nmctx_ferror(struct nmctx *, const char *, ...); 7085c4f8d80SVincenzo Maffione /* nmctx_malloc - allocate memory */ 7095c4f8d80SVincenzo Maffione void *nmctx_malloc(struct nmctx *, size_t); 7105c4f8d80SVincenzo Maffione /* nmctx_free - free memory allocated via nmctx_malloc */ 7115c4f8d80SVincenzo Maffione void nmctx_free(struct nmctx *, void *); 7125c4f8d80SVincenzo Maffione /* nmctx_lock - lock the list of nmem_d */ 7135c4f8d80SVincenzo Maffione void nmctx_lock(struct nmctx *); 7145c4f8d80SVincenzo Maffione /* nmctx_unlock - unlock the list of nmem_d */ 7155c4f8d80SVincenzo Maffione void nmctx_unlock(struct nmctx *); 7165c4f8d80SVincenzo Maffione 7175c4f8d80SVincenzo Maffione #endif /* LIBNETMAP_H_ */ 718