12ff91c17SVincenzo Maffione /*- 22ff91c17SVincenzo Maffione * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 32ff91c17SVincenzo Maffione * 42ff91c17SVincenzo Maffione * Copyright (C) 2018 Vincenzo Maffione 52ff91c17SVincenzo Maffione * All rights reserved. 62ff91c17SVincenzo Maffione * 72ff91c17SVincenzo Maffione * Redistribution and use in source and binary forms, with or without 82ff91c17SVincenzo Maffione * modification, are permitted provided that the following conditions 92ff91c17SVincenzo Maffione * are met: 102ff91c17SVincenzo Maffione * 1. Redistributions of source code must retain the above copyright 112ff91c17SVincenzo Maffione * notice, this list of conditions and the following disclaimer. 122ff91c17SVincenzo Maffione * 2. Redistributions in binary form must reproduce the above copyright 132ff91c17SVincenzo Maffione * notice, this list of conditions and the following disclaimer in the 142ff91c17SVincenzo Maffione * documentation and/or other materials provided with the distribution. 152ff91c17SVincenzo Maffione * 162ff91c17SVincenzo Maffione * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 172ff91c17SVincenzo Maffione * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 182ff91c17SVincenzo Maffione * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 192ff91c17SVincenzo Maffione * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 202ff91c17SVincenzo Maffione * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 212ff91c17SVincenzo Maffione * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 222ff91c17SVincenzo Maffione * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 232ff91c17SVincenzo Maffione * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 242ff91c17SVincenzo Maffione * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 252ff91c17SVincenzo Maffione * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 262ff91c17SVincenzo Maffione * SUCH DAMAGE. 272ff91c17SVincenzo Maffione */ 282ff91c17SVincenzo Maffione 292ff91c17SVincenzo Maffione /* $FreeBSD$ */ 302ff91c17SVincenzo Maffione 312ff91c17SVincenzo Maffione #if defined(__FreeBSD__) 322ff91c17SVincenzo Maffione #include <sys/cdefs.h> /* prerequisite */ 332ff91c17SVincenzo Maffione #include <sys/types.h> 342ff91c17SVincenzo Maffione #include <sys/param.h> /* defines used in kernel.h */ 352ff91c17SVincenzo Maffione #include <sys/filio.h> /* FIONBIO */ 362ff91c17SVincenzo Maffione #include <sys/malloc.h> 372ff91c17SVincenzo Maffione #include <sys/socketvar.h> /* struct socket */ 382ff91c17SVincenzo Maffione #include <sys/socket.h> /* sockaddrs */ 392ff91c17SVincenzo Maffione #include <sys/sysctl.h> 402ff91c17SVincenzo Maffione #include <net/if.h> 412ff91c17SVincenzo Maffione #include <net/if_var.h> 422ff91c17SVincenzo Maffione #include <net/bpf.h> /* BIOCIMMEDIATE */ 432ff91c17SVincenzo Maffione #include <machine/bus.h> /* bus_dmamap_* */ 442ff91c17SVincenzo Maffione #include <sys/endian.h> 452ff91c17SVincenzo Maffione #elif defined(linux) 462ff91c17SVincenzo Maffione #include "bsd_glue.h" 472ff91c17SVincenzo Maffione #elif defined(__APPLE__) 482ff91c17SVincenzo Maffione #warning OSX support is only partial 492ff91c17SVincenzo Maffione #include "osx_glue.h" 502ff91c17SVincenzo Maffione #elif defined (_WIN32) 512ff91c17SVincenzo Maffione #include "win_glue.h" 522ff91c17SVincenzo Maffione #endif 532ff91c17SVincenzo Maffione 542ff91c17SVincenzo Maffione /* 552ff91c17SVincenzo Maffione * common headers 562ff91c17SVincenzo Maffione */ 572ff91c17SVincenzo Maffione #include <net/netmap.h> 582ff91c17SVincenzo Maffione #include <dev/netmap/netmap_kern.h> 59b6e66be2SVincenzo Maffione #include <dev/netmap/netmap_bdg.h> 602ff91c17SVincenzo Maffione 612ff91c17SVincenzo Maffione static int 622ff91c17SVincenzo Maffione nmreq_register_from_legacy(struct nmreq *nmr, struct nmreq_header *hdr, 632ff91c17SVincenzo Maffione struct nmreq_register *req) 642ff91c17SVincenzo Maffione { 652ff91c17SVincenzo Maffione req->nr_offset = nmr->nr_offset; 662ff91c17SVincenzo Maffione req->nr_memsize = nmr->nr_memsize; 672ff91c17SVincenzo Maffione req->nr_tx_slots = nmr->nr_tx_slots; 682ff91c17SVincenzo Maffione req->nr_rx_slots = nmr->nr_rx_slots; 692ff91c17SVincenzo Maffione req->nr_tx_rings = nmr->nr_tx_rings; 702ff91c17SVincenzo Maffione req->nr_rx_rings = nmr->nr_rx_rings; 71d12354a5SVincenzo Maffione req->nr_host_tx_rings = 0; 72d12354a5SVincenzo Maffione req->nr_host_rx_rings = 0; 732ff91c17SVincenzo Maffione req->nr_mem_id = nmr->nr_arg2; 742ff91c17SVincenzo Maffione req->nr_ringid = nmr->nr_ringid & NETMAP_RING_MASK; 752ff91c17SVincenzo Maffione if ((nmr->nr_flags & NR_REG_MASK) == NR_REG_DEFAULT) { 762ff91c17SVincenzo Maffione /* Convert the older nmr->nr_ringid (original 772ff91c17SVincenzo Maffione * netmap control API) to nmr->nr_flags. */ 782ff91c17SVincenzo Maffione u_int regmode = NR_REG_DEFAULT; 79*ff48ef48SVincenzo Maffione if (nmr->nr_ringid & NETMAP_SW_RING) { 802ff91c17SVincenzo Maffione regmode = NR_REG_SW; 81*ff48ef48SVincenzo Maffione } else if (nmr->nr_ringid & NETMAP_HW_RING) { 822ff91c17SVincenzo Maffione regmode = NR_REG_ONE_NIC; 832ff91c17SVincenzo Maffione } else { 842ff91c17SVincenzo Maffione regmode = NR_REG_ALL_NIC; 852ff91c17SVincenzo Maffione } 86b6e66be2SVincenzo Maffione req->nr_mode = regmode; 87b6e66be2SVincenzo Maffione } else { 882ff91c17SVincenzo Maffione req->nr_mode = nmr->nr_flags & NR_REG_MASK; 89b6e66be2SVincenzo Maffione } 90b6e66be2SVincenzo Maffione 912ff91c17SVincenzo Maffione /* Fix nr_name, nr_mode and nr_ringid to handle pipe requests. */ 922ff91c17SVincenzo Maffione if (req->nr_mode == NR_REG_PIPE_MASTER || 932ff91c17SVincenzo Maffione req->nr_mode == NR_REG_PIPE_SLAVE) { 942ff91c17SVincenzo Maffione char suffix[10]; 952ff91c17SVincenzo Maffione snprintf(suffix, sizeof(suffix), "%c%d", 962ff91c17SVincenzo Maffione (req->nr_mode == NR_REG_PIPE_MASTER ? '{' : '}'), 972ff91c17SVincenzo Maffione req->nr_ringid); 982ff91c17SVincenzo Maffione if (strlen(hdr->nr_name) + strlen(suffix) 992ff91c17SVincenzo Maffione >= sizeof(hdr->nr_name)) { 1002ff91c17SVincenzo Maffione /* No space for the pipe suffix. */ 1012ff91c17SVincenzo Maffione return ENOBUFS; 1022ff91c17SVincenzo Maffione } 103760fa2abSVincenzo Maffione strlcat(hdr->nr_name, suffix, sizeof(hdr->nr_name)); 1042ff91c17SVincenzo Maffione req->nr_mode = NR_REG_ALL_NIC; 1052ff91c17SVincenzo Maffione req->nr_ringid = 0; 1062ff91c17SVincenzo Maffione } 1072ff91c17SVincenzo Maffione req->nr_flags = nmr->nr_flags & (~NR_REG_MASK); 1082ff91c17SVincenzo Maffione if (nmr->nr_ringid & NETMAP_NO_TX_POLL) { 1092ff91c17SVincenzo Maffione req->nr_flags |= NR_NO_TX_POLL; 1102ff91c17SVincenzo Maffione } 1112ff91c17SVincenzo Maffione if (nmr->nr_ringid & NETMAP_DO_RX_POLL) { 1122ff91c17SVincenzo Maffione req->nr_flags |= NR_DO_RX_POLL; 1132ff91c17SVincenzo Maffione } 1142ff91c17SVincenzo Maffione /* nmr->nr_arg1 (nr_pipes) ignored */ 1152ff91c17SVincenzo Maffione req->nr_extra_bufs = nmr->nr_arg3; 1162ff91c17SVincenzo Maffione 1172ff91c17SVincenzo Maffione return 0; 1182ff91c17SVincenzo Maffione } 1192ff91c17SVincenzo Maffione 1202ff91c17SVincenzo Maffione /* Convert the legacy 'nmr' struct into one of the nmreq_xyz structs 1212ff91c17SVincenzo Maffione * (new API). The new struct is dynamically allocated. */ 1222ff91c17SVincenzo Maffione static struct nmreq_header * 1232ff91c17SVincenzo Maffione nmreq_from_legacy(struct nmreq *nmr, u_long ioctl_cmd) 1242ff91c17SVincenzo Maffione { 1252ff91c17SVincenzo Maffione struct nmreq_header *hdr = nm_os_malloc(sizeof(*hdr)); 1262ff91c17SVincenzo Maffione 1272ff91c17SVincenzo Maffione if (hdr == NULL) { 1282ff91c17SVincenzo Maffione goto oom; 1292ff91c17SVincenzo Maffione } 1302ff91c17SVincenzo Maffione 1312ff91c17SVincenzo Maffione /* Sanitize nmr->nr_name by adding the string terminator. */ 1322ff91c17SVincenzo Maffione if (ioctl_cmd == NIOCGINFO || ioctl_cmd == NIOCREGIF) { 1332ff91c17SVincenzo Maffione nmr->nr_name[sizeof(nmr->nr_name) - 1] = '\0'; 1342ff91c17SVincenzo Maffione } 1352ff91c17SVincenzo Maffione 1362ff91c17SVincenzo Maffione /* First prepare the request header. */ 1372ff91c17SVincenzo Maffione hdr->nr_version = NETMAP_API; /* new API */ 138b6e66be2SVincenzo Maffione strlcpy(hdr->nr_name, nmr->nr_name, sizeof(nmr->nr_name)); 139cfa866f6SMatt Macy hdr->nr_options = (uintptr_t)NULL; 140cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)NULL; 1412ff91c17SVincenzo Maffione 1422ff91c17SVincenzo Maffione switch (ioctl_cmd) { 1432ff91c17SVincenzo Maffione case NIOCREGIF: { 1442ff91c17SVincenzo Maffione switch (nmr->nr_cmd) { 1452ff91c17SVincenzo Maffione case 0: { 1462ff91c17SVincenzo Maffione /* Regular NIOCREGIF operation. */ 1472ff91c17SVincenzo Maffione struct nmreq_register *req = nm_os_malloc(sizeof(*req)); 1482ff91c17SVincenzo Maffione if (!req) { goto oom; } 149cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 1502ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_REGISTER; 1512ff91c17SVincenzo Maffione if (nmreq_register_from_legacy(nmr, hdr, req)) { 1522ff91c17SVincenzo Maffione goto oom; 1532ff91c17SVincenzo Maffione } 1542ff91c17SVincenzo Maffione break; 1552ff91c17SVincenzo Maffione } 1562ff91c17SVincenzo Maffione case NETMAP_BDG_ATTACH: { 1572ff91c17SVincenzo Maffione struct nmreq_vale_attach *req = nm_os_malloc(sizeof(*req)); 1582ff91c17SVincenzo Maffione if (!req) { goto oom; } 159cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 1602ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_VALE_ATTACH; 1612ff91c17SVincenzo Maffione if (nmreq_register_from_legacy(nmr, hdr, &req->reg)) { 1622ff91c17SVincenzo Maffione goto oom; 1632ff91c17SVincenzo Maffione } 1642ff91c17SVincenzo Maffione /* Fix nr_mode, starting from nr_arg1. */ 1652ff91c17SVincenzo Maffione if (nmr->nr_arg1 & NETMAP_BDG_HOST) { 1662ff91c17SVincenzo Maffione req->reg.nr_mode = NR_REG_NIC_SW; 1672ff91c17SVincenzo Maffione } else { 1682ff91c17SVincenzo Maffione req->reg.nr_mode = NR_REG_ALL_NIC; 1692ff91c17SVincenzo Maffione } 1702ff91c17SVincenzo Maffione break; 1712ff91c17SVincenzo Maffione } 1722ff91c17SVincenzo Maffione case NETMAP_BDG_DETACH: { 1732ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_VALE_DETACH; 174cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)nm_os_malloc(sizeof(struct nmreq_vale_detach)); 1752ff91c17SVincenzo Maffione break; 1762ff91c17SVincenzo Maffione } 1772ff91c17SVincenzo Maffione case NETMAP_BDG_VNET_HDR: 1782ff91c17SVincenzo Maffione case NETMAP_VNET_HDR_GET: { 1792ff91c17SVincenzo Maffione struct nmreq_port_hdr *req = nm_os_malloc(sizeof(*req)); 1802ff91c17SVincenzo Maffione if (!req) { goto oom; } 181cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 1822ff91c17SVincenzo Maffione hdr->nr_reqtype = (nmr->nr_cmd == NETMAP_BDG_VNET_HDR) ? 1832ff91c17SVincenzo Maffione NETMAP_REQ_PORT_HDR_SET : NETMAP_REQ_PORT_HDR_GET; 1842ff91c17SVincenzo Maffione req->nr_hdr_len = nmr->nr_arg1; 1852ff91c17SVincenzo Maffione break; 1862ff91c17SVincenzo Maffione } 1872ff91c17SVincenzo Maffione case NETMAP_BDG_NEWIF : { 1882ff91c17SVincenzo Maffione struct nmreq_vale_newif *req = nm_os_malloc(sizeof(*req)); 1892ff91c17SVincenzo Maffione if (!req) { goto oom; } 190cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 1912ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_VALE_NEWIF; 1922ff91c17SVincenzo Maffione req->nr_tx_slots = nmr->nr_tx_slots; 1932ff91c17SVincenzo Maffione req->nr_rx_slots = nmr->nr_rx_slots; 1942ff91c17SVincenzo Maffione req->nr_tx_rings = nmr->nr_tx_rings; 1952ff91c17SVincenzo Maffione req->nr_rx_rings = nmr->nr_rx_rings; 1962ff91c17SVincenzo Maffione req->nr_mem_id = nmr->nr_arg2; 1972ff91c17SVincenzo Maffione break; 1982ff91c17SVincenzo Maffione } 1992ff91c17SVincenzo Maffione case NETMAP_BDG_DELIF: { 2002ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_VALE_DELIF; 2012ff91c17SVincenzo Maffione break; 2022ff91c17SVincenzo Maffione } 2032ff91c17SVincenzo Maffione case NETMAP_BDG_POLLING_ON: 2042ff91c17SVincenzo Maffione case NETMAP_BDG_POLLING_OFF: { 2052ff91c17SVincenzo Maffione struct nmreq_vale_polling *req = nm_os_malloc(sizeof(*req)); 2062ff91c17SVincenzo Maffione if (!req) { goto oom; } 207cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 2082ff91c17SVincenzo Maffione hdr->nr_reqtype = (nmr->nr_cmd == NETMAP_BDG_POLLING_ON) ? 2092ff91c17SVincenzo Maffione NETMAP_REQ_VALE_POLLING_ENABLE : 2102ff91c17SVincenzo Maffione NETMAP_REQ_VALE_POLLING_DISABLE; 2112ff91c17SVincenzo Maffione switch (nmr->nr_flags & NR_REG_MASK) { 2122ff91c17SVincenzo Maffione default: 2132ff91c17SVincenzo Maffione req->nr_mode = 0; /* invalid */ 2142ff91c17SVincenzo Maffione break; 2152ff91c17SVincenzo Maffione case NR_REG_ONE_NIC: 2162ff91c17SVincenzo Maffione req->nr_mode = NETMAP_POLLING_MODE_MULTI_CPU; 2172ff91c17SVincenzo Maffione break; 2182ff91c17SVincenzo Maffione case NR_REG_ALL_NIC: 2192ff91c17SVincenzo Maffione req->nr_mode = NETMAP_POLLING_MODE_SINGLE_CPU; 2202ff91c17SVincenzo Maffione break; 2212ff91c17SVincenzo Maffione } 2222ff91c17SVincenzo Maffione req->nr_first_cpu_id = nmr->nr_ringid & NETMAP_RING_MASK; 2232ff91c17SVincenzo Maffione req->nr_num_polling_cpus = nmr->nr_arg1; 2242ff91c17SVincenzo Maffione break; 2252ff91c17SVincenzo Maffione } 2262ff91c17SVincenzo Maffione case NETMAP_PT_HOST_CREATE: 2272ff91c17SVincenzo Maffione case NETMAP_PT_HOST_DELETE: { 228b6e66be2SVincenzo Maffione nm_prerr("Netmap passthrough not supported yet"); 2292ff91c17SVincenzo Maffione return NULL; 2302ff91c17SVincenzo Maffione break; 2312ff91c17SVincenzo Maffione } 2322ff91c17SVincenzo Maffione } 2332ff91c17SVincenzo Maffione break; 2342ff91c17SVincenzo Maffione } 2352ff91c17SVincenzo Maffione case NIOCGINFO: { 2362ff91c17SVincenzo Maffione if (nmr->nr_cmd == NETMAP_BDG_LIST) { 2372ff91c17SVincenzo Maffione struct nmreq_vale_list *req = nm_os_malloc(sizeof(*req)); 2382ff91c17SVincenzo Maffione if (!req) { goto oom; } 239cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 2402ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_VALE_LIST; 2412ff91c17SVincenzo Maffione req->nr_bridge_idx = nmr->nr_arg1; 2422ff91c17SVincenzo Maffione req->nr_port_idx = nmr->nr_arg2; 2432ff91c17SVincenzo Maffione } else { 2442ff91c17SVincenzo Maffione /* Regular NIOCGINFO. */ 2452ff91c17SVincenzo Maffione struct nmreq_port_info_get *req = nm_os_malloc(sizeof(*req)); 2462ff91c17SVincenzo Maffione if (!req) { goto oom; } 247cfa866f6SMatt Macy hdr->nr_body = (uintptr_t)req; 2482ff91c17SVincenzo Maffione hdr->nr_reqtype = NETMAP_REQ_PORT_INFO_GET; 2492ff91c17SVincenzo Maffione req->nr_memsize = nmr->nr_memsize; 2502ff91c17SVincenzo Maffione req->nr_tx_slots = nmr->nr_tx_slots; 2512ff91c17SVincenzo Maffione req->nr_rx_slots = nmr->nr_rx_slots; 2522ff91c17SVincenzo Maffione req->nr_tx_rings = nmr->nr_tx_rings; 2532ff91c17SVincenzo Maffione req->nr_rx_rings = nmr->nr_rx_rings; 254d12354a5SVincenzo Maffione req->nr_host_tx_rings = 0; 255d12354a5SVincenzo Maffione req->nr_host_rx_rings = 0; 2562ff91c17SVincenzo Maffione req->nr_mem_id = nmr->nr_arg2; 2572ff91c17SVincenzo Maffione } 2582ff91c17SVincenzo Maffione break; 2592ff91c17SVincenzo Maffione } 2602ff91c17SVincenzo Maffione } 2612ff91c17SVincenzo Maffione 2622ff91c17SVincenzo Maffione return hdr; 2632ff91c17SVincenzo Maffione oom: 2642ff91c17SVincenzo Maffione if (hdr) { 2652ff91c17SVincenzo Maffione if (hdr->nr_body) { 266cfa866f6SMatt Macy nm_os_free((void *)(uintptr_t)hdr->nr_body); 2672ff91c17SVincenzo Maffione } 2682ff91c17SVincenzo Maffione nm_os_free(hdr); 2692ff91c17SVincenzo Maffione } 270b6e66be2SVincenzo Maffione nm_prerr("Failed to allocate memory for nmreq_xyz struct"); 2712ff91c17SVincenzo Maffione 2722ff91c17SVincenzo Maffione return NULL; 2732ff91c17SVincenzo Maffione } 2742ff91c17SVincenzo Maffione 2752ff91c17SVincenzo Maffione static void 2762ff91c17SVincenzo Maffione nmreq_register_to_legacy(const struct nmreq_register *req, struct nmreq *nmr) 2772ff91c17SVincenzo Maffione { 2782ff91c17SVincenzo Maffione nmr->nr_offset = req->nr_offset; 2792ff91c17SVincenzo Maffione nmr->nr_memsize = req->nr_memsize; 2802ff91c17SVincenzo Maffione nmr->nr_tx_slots = req->nr_tx_slots; 2812ff91c17SVincenzo Maffione nmr->nr_rx_slots = req->nr_rx_slots; 2822ff91c17SVincenzo Maffione nmr->nr_tx_rings = req->nr_tx_rings; 2832ff91c17SVincenzo Maffione nmr->nr_rx_rings = req->nr_rx_rings; 2842ff91c17SVincenzo Maffione nmr->nr_arg2 = req->nr_mem_id; 2852ff91c17SVincenzo Maffione nmr->nr_arg3 = req->nr_extra_bufs; 2862ff91c17SVincenzo Maffione } 2872ff91c17SVincenzo Maffione 2882ff91c17SVincenzo Maffione /* Convert a nmreq_xyz struct (new API) to the legacy 'nmr' struct. 2892ff91c17SVincenzo Maffione * It also frees the nmreq_xyz struct, as it was allocated by 2902ff91c17SVincenzo Maffione * nmreq_from_legacy(). */ 2912ff91c17SVincenzo Maffione static int 2922ff91c17SVincenzo Maffione nmreq_to_legacy(struct nmreq_header *hdr, struct nmreq *nmr) 2932ff91c17SVincenzo Maffione { 2942ff91c17SVincenzo Maffione int ret = 0; 2952ff91c17SVincenzo Maffione 2962ff91c17SVincenzo Maffione /* We only write-back the fields that the user expects to be 2972ff91c17SVincenzo Maffione * written back. */ 2982ff91c17SVincenzo Maffione switch (hdr->nr_reqtype) { 2992ff91c17SVincenzo Maffione case NETMAP_REQ_REGISTER: { 3002ff91c17SVincenzo Maffione struct nmreq_register *req = 301cfa866f6SMatt Macy (struct nmreq_register *)(uintptr_t)hdr->nr_body; 3022ff91c17SVincenzo Maffione nmreq_register_to_legacy(req, nmr); 3032ff91c17SVincenzo Maffione break; 3042ff91c17SVincenzo Maffione } 3052ff91c17SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET: { 3062ff91c17SVincenzo Maffione struct nmreq_port_info_get *req = 307cfa866f6SMatt Macy (struct nmreq_port_info_get *)(uintptr_t)hdr->nr_body; 3082ff91c17SVincenzo Maffione nmr->nr_memsize = req->nr_memsize; 3092ff91c17SVincenzo Maffione nmr->nr_tx_slots = req->nr_tx_slots; 3102ff91c17SVincenzo Maffione nmr->nr_rx_slots = req->nr_rx_slots; 3112ff91c17SVincenzo Maffione nmr->nr_tx_rings = req->nr_tx_rings; 3122ff91c17SVincenzo Maffione nmr->nr_rx_rings = req->nr_rx_rings; 3132ff91c17SVincenzo Maffione nmr->nr_arg2 = req->nr_mem_id; 3142ff91c17SVincenzo Maffione break; 3152ff91c17SVincenzo Maffione } 3162ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH: { 3172ff91c17SVincenzo Maffione struct nmreq_vale_attach *req = 318cfa866f6SMatt Macy (struct nmreq_vale_attach *)(uintptr_t)hdr->nr_body; 3192ff91c17SVincenzo Maffione nmreq_register_to_legacy(&req->reg, nmr); 3202ff91c17SVincenzo Maffione break; 3212ff91c17SVincenzo Maffione } 3222ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_DETACH: { 3232ff91c17SVincenzo Maffione break; 3242ff91c17SVincenzo Maffione } 3252ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_LIST: { 3262ff91c17SVincenzo Maffione struct nmreq_vale_list *req = 327cfa866f6SMatt Macy (struct nmreq_vale_list *)(uintptr_t)hdr->nr_body; 328b6e66be2SVincenzo Maffione strlcpy(nmr->nr_name, hdr->nr_name, sizeof(nmr->nr_name)); 3292ff91c17SVincenzo Maffione nmr->nr_arg1 = req->nr_bridge_idx; 3302ff91c17SVincenzo Maffione nmr->nr_arg2 = req->nr_port_idx; 3312ff91c17SVincenzo Maffione break; 3322ff91c17SVincenzo Maffione } 3332ff91c17SVincenzo Maffione case NETMAP_REQ_PORT_HDR_SET: 3342ff91c17SVincenzo Maffione case NETMAP_REQ_PORT_HDR_GET: { 3352ff91c17SVincenzo Maffione struct nmreq_port_hdr *req = 336cfa866f6SMatt Macy (struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body; 3372ff91c17SVincenzo Maffione nmr->nr_arg1 = req->nr_hdr_len; 3382ff91c17SVincenzo Maffione break; 3392ff91c17SVincenzo Maffione } 3402ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF: { 3412ff91c17SVincenzo Maffione struct nmreq_vale_newif *req = 342cfa866f6SMatt Macy (struct nmreq_vale_newif *)(uintptr_t)hdr->nr_body; 3432ff91c17SVincenzo Maffione nmr->nr_tx_slots = req->nr_tx_slots; 3442ff91c17SVincenzo Maffione nmr->nr_rx_slots = req->nr_rx_slots; 3452ff91c17SVincenzo Maffione nmr->nr_tx_rings = req->nr_tx_rings; 3462ff91c17SVincenzo Maffione nmr->nr_rx_rings = req->nr_rx_rings; 3472ff91c17SVincenzo Maffione nmr->nr_arg2 = req->nr_mem_id; 3482ff91c17SVincenzo Maffione break; 3492ff91c17SVincenzo Maffione } 3502ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_DELIF: 3512ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_ENABLE: 3522ff91c17SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_DISABLE: { 3532ff91c17SVincenzo Maffione break; 3542ff91c17SVincenzo Maffione } 3552ff91c17SVincenzo Maffione } 3562ff91c17SVincenzo Maffione 3572ff91c17SVincenzo Maffione return ret; 3582ff91c17SVincenzo Maffione } 3592ff91c17SVincenzo Maffione 3602ff91c17SVincenzo Maffione int 3612ff91c17SVincenzo Maffione netmap_ioctl_legacy(struct netmap_priv_d *priv, u_long cmd, caddr_t data, 3622ff91c17SVincenzo Maffione struct thread *td) 3632ff91c17SVincenzo Maffione { 3642ff91c17SVincenzo Maffione int error = 0; 3652ff91c17SVincenzo Maffione 3662ff91c17SVincenzo Maffione switch (cmd) { 3672ff91c17SVincenzo Maffione case NIOCGINFO: 3682ff91c17SVincenzo Maffione case NIOCREGIF: { 3692ff91c17SVincenzo Maffione /* Request for the legacy control API. Convert it to a 3702ff91c17SVincenzo Maffione * NIOCCTRL request. */ 3712ff91c17SVincenzo Maffione struct nmreq *nmr = (struct nmreq *) data; 37275f4f3edSVincenzo Maffione struct nmreq_header *hdr; 37375f4f3edSVincenzo Maffione 374d12354a5SVincenzo Maffione if (nmr->nr_version < 14) { 375d12354a5SVincenzo Maffione nm_prerr("Minimum supported API is 14 (requested %u)", 37675f4f3edSVincenzo Maffione nmr->nr_version); 37775f4f3edSVincenzo Maffione return EINVAL; 37875f4f3edSVincenzo Maffione } 37975f4f3edSVincenzo Maffione hdr = nmreq_from_legacy(nmr, cmd); 3802ff91c17SVincenzo Maffione if (hdr == NULL) { /* out of memory */ 3812ff91c17SVincenzo Maffione return ENOMEM; 3822ff91c17SVincenzo Maffione } 3832ff91c17SVincenzo Maffione error = netmap_ioctl(priv, NIOCCTRL, (caddr_t)hdr, td, 3842ff91c17SVincenzo Maffione /*nr_body_is_user=*/0); 3852ff91c17SVincenzo Maffione if (error == 0) { 3862ff91c17SVincenzo Maffione nmreq_to_legacy(hdr, nmr); 3872ff91c17SVincenzo Maffione } 3882ff91c17SVincenzo Maffione if (hdr->nr_body) { 389cfa866f6SMatt Macy nm_os_free((void *)(uintptr_t)hdr->nr_body); 3902ff91c17SVincenzo Maffione } 3912ff91c17SVincenzo Maffione nm_os_free(hdr); 3922ff91c17SVincenzo Maffione break; 3932ff91c17SVincenzo Maffione } 3942ff91c17SVincenzo Maffione #ifdef WITH_VALE 3952ff91c17SVincenzo Maffione case NIOCCONFIG: { 3962ff91c17SVincenzo Maffione struct nm_ifreq *nr = (struct nm_ifreq *)data; 3972ff91c17SVincenzo Maffione error = netmap_bdg_config(nr); 3982ff91c17SVincenzo Maffione break; 3992ff91c17SVincenzo Maffione } 4002ff91c17SVincenzo Maffione #endif 4012ff91c17SVincenzo Maffione #ifdef __FreeBSD__ 4022ff91c17SVincenzo Maffione case FIONBIO: 4032ff91c17SVincenzo Maffione case FIOASYNC: 40475f4f3edSVincenzo Maffione /* FIONBIO/FIOASYNC are no-ops. */ 4052ff91c17SVincenzo Maffione break; 4062ff91c17SVincenzo Maffione 4072ff91c17SVincenzo Maffione case BIOCIMMEDIATE: 4082ff91c17SVincenzo Maffione case BIOCGHDRCMPLT: 4092ff91c17SVincenzo Maffione case BIOCSHDRCMPLT: 4102ff91c17SVincenzo Maffione case BIOCSSEESENT: 41175f4f3edSVincenzo Maffione /* Ignore these commands. */ 4122ff91c17SVincenzo Maffione break; 4132ff91c17SVincenzo Maffione 4142ff91c17SVincenzo Maffione default: /* allow device-specific ioctls */ 4152ff91c17SVincenzo Maffione { 4162ff91c17SVincenzo Maffione struct nmreq *nmr = (struct nmreq *)data; 4172ff91c17SVincenzo Maffione struct ifnet *ifp = ifunit_ref(nmr->nr_name); 4182ff91c17SVincenzo Maffione if (ifp == NULL) { 4192ff91c17SVincenzo Maffione error = ENXIO; 4202ff91c17SVincenzo Maffione } else { 4212ff91c17SVincenzo Maffione struct socket so; 4222ff91c17SVincenzo Maffione 4232ff91c17SVincenzo Maffione bzero(&so, sizeof(so)); 4242ff91c17SVincenzo Maffione so.so_vnet = ifp->if_vnet; 4252ff91c17SVincenzo Maffione // so->so_proto not null. 4262ff91c17SVincenzo Maffione error = ifioctl(&so, cmd, data, td); 4272ff91c17SVincenzo Maffione if_rele(ifp); 4282ff91c17SVincenzo Maffione } 4292ff91c17SVincenzo Maffione break; 4302ff91c17SVincenzo Maffione } 4312ff91c17SVincenzo Maffione 4322ff91c17SVincenzo Maffione #else /* linux */ 4332ff91c17SVincenzo Maffione default: 4342ff91c17SVincenzo Maffione error = EOPNOTSUPP; 4352ff91c17SVincenzo Maffione #endif /* linux */ 4362ff91c17SVincenzo Maffione } 4372ff91c17SVincenzo Maffione 4382ff91c17SVincenzo Maffione return error; 4392ff91c17SVincenzo Maffione } 440