1 /* 2 * Copyright (C) 2018 Giuseppe Lettieri 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 /* $FreeBSD$ */ 27 28 #if defined(__FreeBSD__) 29 #include <sys/cdefs.h> /* prerequisite */ 30 31 #include <sys/types.h> 32 #include <sys/errno.h> 33 #include <sys/param.h> /* defines used in kernel.h */ 34 #include <sys/kernel.h> /* types used in module initialization */ 35 #include <sys/malloc.h> 36 #include <sys/poll.h> 37 #include <sys/lock.h> 38 #include <sys/rwlock.h> 39 #include <sys/selinfo.h> 40 #include <sys/sysctl.h> 41 #include <sys/socket.h> /* sockaddrs */ 42 #include <net/if.h> 43 #include <net/if_var.h> 44 #include <machine/bus.h> /* bus_dmamap_* */ 45 #include <sys/refcount.h> 46 47 48 #elif defined(linux) 49 50 #include "bsd_glue.h" 51 52 #elif defined(__APPLE__) 53 54 #warning OSX support is only partial 55 #include "osx_glue.h" 56 57 #elif defined(_WIN32) 58 #include "win_glue.h" 59 60 #else 61 62 #error Unsupported platform 63 64 #endif /* unsupported */ 65 66 /* 67 * common headers 68 */ 69 70 #include <net/netmap.h> 71 #include <dev/netmap/netmap_kern.h> 72 #include <dev/netmap/netmap_mem2.h> 73 74 #ifdef WITH_NMNULL 75 76 static int 77 netmap_null_txsync(struct netmap_kring *kring, int flags) 78 { 79 (void)kring; 80 (void)flags; 81 return 0; 82 } 83 84 static int 85 netmap_null_rxsync(struct netmap_kring *kring, int flags) 86 { 87 (void)kring; 88 (void)flags; 89 return 0; 90 } 91 92 static int 93 netmap_null_krings_create(struct netmap_adapter *na) 94 { 95 return netmap_krings_create(na, 0); 96 } 97 98 static void 99 netmap_null_krings_delete(struct netmap_adapter *na) 100 { 101 netmap_krings_delete(na); 102 } 103 104 static int 105 netmap_null_reg(struct netmap_adapter *na, int onoff) 106 { 107 if (na->active_fds == 0) { 108 if (onoff) 109 na->na_flags |= NAF_NETMAP_ON; 110 else 111 na->na_flags &= ~NAF_NETMAP_ON; 112 } 113 return 0; 114 } 115 116 static int 117 netmap_null_bdg_attach(const char *name, struct netmap_adapter *na, 118 struct nm_bridge *b) 119 { 120 (void)name; 121 (void)na; 122 (void)b; 123 return EINVAL; 124 } 125 126 int 127 netmap_get_null_na(struct nmreq_header *hdr, struct netmap_adapter **na, 128 struct netmap_mem_d *nmd, int create) 129 { 130 struct nmreq_register *req = (struct nmreq_register *)(uintptr_t)hdr->nr_body; 131 struct netmap_null_adapter *nna; 132 int error; 133 134 if (req->nr_mode != NR_REG_NULL) { 135 nm_prdis("not a null port"); 136 return 0; 137 } 138 139 if (!create) { 140 nm_prerr("null ports cannot be re-opened"); 141 return EINVAL; 142 } 143 144 if (nmd == NULL) { 145 nm_prerr("null ports must use an existing allocator"); 146 return EINVAL; 147 } 148 149 nna = nm_os_malloc(sizeof(*nna)); 150 if (nna == NULL) { 151 error = ENOMEM; 152 goto err; 153 } 154 snprintf(nna->up.name, sizeof(nna->up.name), "null:%s", hdr->nr_name); 155 156 nna->up.nm_txsync = netmap_null_txsync; 157 nna->up.nm_rxsync = netmap_null_rxsync; 158 nna->up.nm_register = netmap_null_reg; 159 nna->up.nm_krings_create = netmap_null_krings_create; 160 nna->up.nm_krings_delete = netmap_null_krings_delete; 161 nna->up.nm_bdg_attach = netmap_null_bdg_attach; 162 nna->up.nm_mem = netmap_mem_get(nmd); 163 164 nna->up.num_tx_rings = req->nr_tx_rings; 165 nna->up.num_rx_rings = req->nr_rx_rings; 166 nna->up.num_tx_desc = req->nr_tx_slots; 167 nna->up.num_rx_desc = req->nr_rx_slots; 168 error = netmap_attach_common(&nna->up); 169 if (error) 170 goto free_nna; 171 *na = &nna->up; 172 netmap_adapter_get(*na); 173 nm_prdis("created null %s", nna->up.name); 174 175 return 0; 176 177 free_nna: 178 nm_os_free(nna); 179 err: 180 return error; 181 } 182 183 184 #endif /* WITH_NMNULL */ 185