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>
59b321acabSVincenzo Maffione #include <dev/netmap/netmap_bdg.h>
602ff91c17SVincenzo Maffione
612ff91c17SVincenzo Maffione static int
nmreq_register_from_legacy(struct nmreq * nmr,struct nmreq_header * hdr,struct nmreq_register * req)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;
71*7af42e83SVincenzo Maffione req->nr_host_tx_rings = 0;
72*7af42e83SVincenzo 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;
792ff91c17SVincenzo Maffione if (req->nr_ringid & NETMAP_SW_RING) {
802ff91c17SVincenzo Maffione regmode = NR_REG_SW;
812ff91c17SVincenzo Maffione } else if (req->nr_ringid & NETMAP_HW_RING) {
822ff91c17SVincenzo Maffione regmode = NR_REG_ONE_NIC;
832ff91c17SVincenzo Maffione } else {
842ff91c17SVincenzo Maffione regmode = NR_REG_ALL_NIC;
852ff91c17SVincenzo Maffione }
86b321acabSVincenzo Maffione req->nr_mode = regmode;
87b321acabSVincenzo Maffione } else {
882ff91c17SVincenzo Maffione req->nr_mode = nmr->nr_flags & NR_REG_MASK;
89b321acabSVincenzo Maffione }
90b321acabSVincenzo 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 }
1032ff91c17SVincenzo Maffione strncat(hdr->nr_name, suffix, strlen(suffix));
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 *
nmreq_from_legacy(struct nmreq * nmr,u_long ioctl_cmd)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 */
138b321acabSVincenzo 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: {
228b321acabSVincenzo 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;
254*7af42e83SVincenzo Maffione req->nr_host_tx_rings = 0;
255*7af42e83SVincenzo 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 }
270b321acabSVincenzo 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
nmreq_register_to_legacy(const struct nmreq_register * req,struct nmreq * nmr)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
nmreq_to_legacy(struct nmreq_header * hdr,struct nmreq * nmr)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;
328b321acabSVincenzo 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
netmap_ioctl_legacy(struct netmap_priv_d * priv,u_long cmd,caddr_t data,struct thread * td)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;
37201e8e2c2SVincenzo Maffione struct nmreq_header *hdr;
37301e8e2c2SVincenzo Maffione
374*7af42e83SVincenzo Maffione if (nmr->nr_version < 14) {
375*7af42e83SVincenzo Maffione nm_prerr("Minimum supported API is 14 (requested %u)",
37601e8e2c2SVincenzo Maffione nmr->nr_version);
37701e8e2c2SVincenzo Maffione return EINVAL;
37801e8e2c2SVincenzo Maffione }
37901e8e2c2SVincenzo 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:
40401e8e2c2SVincenzo 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:
41101e8e2c2SVincenzo 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