1 1.59 riastrad /* $NetBSD: if_virt.c,v 1.59 2021/06/16 00:21:20 riastradh Exp $ */ 2 1.1 pooka 3 1.1 pooka /* 4 1.32 pooka * Copyright (c) 2008, 2013 Antti Kantee. All Rights Reserved. 5 1.1 pooka * 6 1.1 pooka * Redistribution and use in source and binary forms, with or without 7 1.1 pooka * modification, are permitted provided that the following conditions 8 1.1 pooka * are met: 9 1.1 pooka * 1. Redistributions of source code must retain the above copyright 10 1.1 pooka * notice, this list of conditions and the following disclaimer. 11 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 pooka * notice, this list of conditions and the following disclaimer in the 13 1.1 pooka * documentation and/or other materials provided with the distribution. 14 1.1 pooka * 15 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 1.1 pooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 pooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 pooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 pooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 pooka * SUCH DAMAGE. 26 1.1 pooka */ 27 1.1 pooka 28 1.5 pooka #include <sys/cdefs.h> 29 1.59 riastrad __KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.59 2021/06/16 00:21:20 riastradh Exp $"); 30 1.5 pooka 31 1.1 pooka #include <sys/param.h> 32 1.21 pooka #include <sys/kernel.h> 33 1.1 pooka #include <sys/kmem.h> 34 1.26 tls #include <sys/cprng.h> 35 1.44 pooka #include <sys/module.h> 36 1.1 pooka 37 1.15 pooka #include <net/bpf.h> 38 1.1 pooka #include <net/if.h> 39 1.39 pooka #include <net/if_dl.h> 40 1.1 pooka #include <net/if_ether.h> 41 1.1 pooka 42 1.1 pooka #include <netinet/in.h> 43 1.1 pooka #include <netinet/in_var.h> 44 1.1 pooka 45 1.36 pooka #include "if_virt.h" 46 1.41 pooka #include "virtif_user.h" 47 1.30 pooka 48 1.1 pooka /* 49 1.32 pooka * Virtual interface. Uses hypercalls to shovel packets back 50 1.32 pooka * and forth. The exact method for shoveling depends on the 51 1.32 pooka * hypercall implementation. 52 1.1 pooka */ 53 1.1 pooka 54 1.1 pooka static int virtif_init(struct ifnet *); 55 1.1 pooka static int virtif_ioctl(struct ifnet *, u_long, void *); 56 1.1 pooka static void virtif_start(struct ifnet *); 57 1.1 pooka static void virtif_stop(struct ifnet *, int); 58 1.1 pooka 59 1.1 pooka struct virtif_sc { 60 1.7 pooka struct ethercom sc_ec; 61 1.30 pooka struct virtif_user *sc_viu; 62 1.39 pooka 63 1.39 pooka int sc_num; 64 1.39 pooka char *sc_linkstr; 65 1.1 pooka }; 66 1.1 pooka 67 1.20 pooka static int virtif_clone(struct if_clone *, int); 68 1.20 pooka static int virtif_unclone(struct ifnet *); 69 1.1 pooka 70 1.36 pooka struct if_clone VIF_CLONER = 71 1.36 pooka IF_CLONE_INITIALIZER(VIF_NAME, virtif_clone, virtif_unclone); 72 1.1 pooka 73 1.34 pooka static int 74 1.39 pooka virtif_create(struct ifnet *ifp) 75 1.1 pooka { 76 1.3 pooka uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0x0a, 0x00, 0x0b, 0x0e, 0x01 }; 77 1.39 pooka char enaddrstr[3*ETHER_ADDR_LEN]; 78 1.39 pooka struct virtif_sc *sc = ifp->if_softc; 79 1.39 pooka int error; 80 1.39 pooka 81 1.39 pooka if (sc->sc_viu) 82 1.39 pooka panic("%s: already created", ifp->if_xname); 83 1.21 pooka 84 1.39 pooka enaddr[2] = cprng_fast32() & 0xff; 85 1.39 pooka enaddr[5] = sc->sc_num & 0xff; 86 1.1 pooka 87 1.39 pooka if ((error = VIFHYPER_CREATE(sc->sc_linkstr, 88 1.39 pooka sc, enaddr, &sc->sc_viu)) != 0) { 89 1.39 pooka printf("VIFHYPER_CREATE failed: %d\n", error); 90 1.31 pooka return error; 91 1.39 pooka } 92 1.39 pooka 93 1.39 pooka ether_ifattach(ifp, enaddr); 94 1.39 pooka ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr); 95 1.39 pooka aprint_normal_ifnet(ifp, "Ethernet address %s\n", enaddrstr); 96 1.39 pooka 97 1.39 pooka IFQ_SET_READY(&ifp->if_snd); 98 1.30 pooka 99 1.39 pooka return 0; 100 1.39 pooka } 101 1.39 pooka 102 1.39 pooka static int 103 1.39 pooka virtif_clone(struct if_clone *ifc, int num) 104 1.39 pooka { 105 1.39 pooka struct virtif_sc *sc; 106 1.39 pooka struct ifnet *ifp; 107 1.39 pooka int error = 0; 108 1.1 pooka 109 1.1 pooka sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 110 1.39 pooka sc->sc_num = num; 111 1.7 pooka ifp = &sc->sc_ec.ec_if; 112 1.47 pooka 113 1.47 pooka if_initname(ifp, VIF_NAME, num); 114 1.1 pooka ifp->if_softc = sc; 115 1.21 pooka 116 1.1 pooka ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 117 1.1 pooka ifp->if_init = virtif_init; 118 1.1 pooka ifp->if_ioctl = virtif_ioctl; 119 1.1 pooka ifp->if_start = virtif_start; 120 1.1 pooka ifp->if_stop = virtif_stop; 121 1.39 pooka ifp->if_mtu = ETHERMTU; 122 1.39 pooka ifp->if_dlt = DLT_EN10MB; 123 1.1 pooka 124 1.59 riastrad if_initialize(ifp); 125 1.50 ozaki if_register(ifp); 126 1.1 pooka 127 1.39 pooka #ifndef RUMP_VIF_LINKSTR 128 1.39 pooka /* 129 1.39 pooka * if the underlying interface does not expect linkstr, we can 130 1.39 pooka * create everything now. Otherwise, we need to wait for 131 1.39 pooka * SIOCSLINKSTR. 132 1.39 pooka */ 133 1.39 pooka #define LINKSTRNUMLEN 16 134 1.39 pooka sc->sc_linkstr = kmem_alloc(LINKSTRNUMLEN, KM_SLEEP); 135 1.55 msaitoh if (sc->sc_linkstr == NULL) { 136 1.55 msaitoh error = ENOMEM; 137 1.59 riastrad goto fail; 138 1.55 msaitoh } 139 1.39 pooka snprintf(sc->sc_linkstr, LINKSTRNUMLEN, "%d", sc->sc_num); 140 1.39 pooka error = virtif_create(ifp); 141 1.21 pooka if (error) { 142 1.59 riastrad fail: 143 1.39 pooka if_detach(ifp); 144 1.55 msaitoh if (sc->sc_linkstr != NULL) 145 1.55 msaitoh kmem_free(sc->sc_linkstr, LINKSTRNUMLEN); 146 1.56 msaitoh #undef LINKSTRNUMLEN 147 1.39 pooka kmem_free(sc, sizeof(*sc)); 148 1.39 pooka ifp->if_softc = NULL; 149 1.21 pooka } 150 1.39 pooka #endif /* !RUMP_VIF_LINKSTR */ 151 1.21 pooka 152 1.21 pooka return error; 153 1.1 pooka } 154 1.1 pooka 155 1.1 pooka static int 156 1.20 pooka virtif_unclone(struct ifnet *ifp) 157 1.20 pooka { 158 1.21 pooka struct virtif_sc *sc = ifp->if_softc; 159 1.42 pooka int rv; 160 1.20 pooka 161 1.39 pooka if (ifp->if_flags & IFF_UP) 162 1.39 pooka return EBUSY; 163 1.21 pooka 164 1.42 pooka if ((rv = VIFHYPER_DYING(sc->sc_viu)) != 0) 165 1.42 pooka return rv; 166 1.30 pooka 167 1.21 pooka virtif_stop(ifp, 1); 168 1.21 pooka if_down(ifp); 169 1.21 pooka 170 1.36 pooka VIFHYPER_DESTROY(sc->sc_viu); 171 1.21 pooka 172 1.21 pooka kmem_free(sc, sizeof(*sc)); 173 1.21 pooka 174 1.21 pooka ether_ifdetach(ifp); 175 1.21 pooka if_detach(ifp); 176 1.21 pooka 177 1.21 pooka return 0; 178 1.20 pooka } 179 1.20 pooka 180 1.20 pooka static int 181 1.1 pooka virtif_init(struct ifnet *ifp) 182 1.1 pooka { 183 1.21 pooka struct virtif_sc *sc = ifp->if_softc; 184 1.1 pooka 185 1.39 pooka if (sc->sc_viu == NULL) 186 1.39 pooka return ENXIO; 187 1.39 pooka 188 1.1 pooka ifp->if_flags |= IFF_RUNNING; 189 1.1 pooka return 0; 190 1.1 pooka } 191 1.1 pooka 192 1.1 pooka static int 193 1.1 pooka virtif_ioctl(struct ifnet *ifp, u_long cmd, void *data) 194 1.1 pooka { 195 1.39 pooka struct virtif_sc *sc = ifp->if_softc; 196 1.39 pooka int rv; 197 1.1 pooka 198 1.39 pooka switch (cmd) { 199 1.39 pooka #ifdef RUMP_VIF_LINKSTR 200 1.39 pooka struct ifdrv *ifd; 201 1.39 pooka size_t linkstrlen; 202 1.39 pooka 203 1.39 pooka #ifndef RUMP_VIF_LINKSTRMAX 204 1.39 pooka #define RUMP_VIF_LINKSTRMAX 4096 205 1.39 pooka #endif 206 1.1 pooka 207 1.39 pooka case SIOCGLINKSTR: 208 1.39 pooka ifd = data; 209 1.1 pooka 210 1.39 pooka if (!sc->sc_linkstr) { 211 1.39 pooka rv = ENOENT; 212 1.39 pooka break; 213 1.39 pooka } 214 1.39 pooka linkstrlen = strlen(sc->sc_linkstr)+1; 215 1.1 pooka 216 1.39 pooka if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) { 217 1.39 pooka ifd->ifd_len = linkstrlen; 218 1.39 pooka rv = 0; 219 1.39 pooka break; 220 1.39 pooka } 221 1.39 pooka if (ifd->ifd_cmd != 0) { 222 1.39 pooka rv = ENOTTY; 223 1.39 pooka break; 224 1.39 pooka } 225 1.1 pooka 226 1.39 pooka rv = copyoutstr(sc->sc_linkstr, 227 1.39 pooka ifd->ifd_data, MIN(ifd->ifd_len,linkstrlen), NULL); 228 1.39 pooka break; 229 1.39 pooka case SIOCSLINKSTR: 230 1.39 pooka if (ifp->if_flags & IFF_UP) { 231 1.39 pooka rv = EBUSY; 232 1.39 pooka break; 233 1.39 pooka } 234 1.1 pooka 235 1.39 pooka ifd = data; 236 1.21 pooka 237 1.39 pooka if (ifd->ifd_cmd == IFLINKSTR_UNSET) { 238 1.39 pooka panic("unset linkstr not implemented"); 239 1.39 pooka } else if (ifd->ifd_cmd != 0) { 240 1.39 pooka rv = ENOTTY; 241 1.39 pooka break; 242 1.39 pooka } else if (sc->sc_linkstr) { 243 1.39 pooka rv = EBUSY; 244 1.39 pooka break; 245 1.39 pooka } 246 1.1 pooka 247 1.39 pooka if (ifd->ifd_len > RUMP_VIF_LINKSTRMAX) { 248 1.39 pooka rv = E2BIG; 249 1.39 pooka break; 250 1.39 pooka } else if (ifd->ifd_len < 1) { 251 1.39 pooka rv = EINVAL; 252 1.39 pooka break; 253 1.39 pooka } 254 1.21 pooka 255 1.1 pooka 256 1.39 pooka sc->sc_linkstr = kmem_alloc(ifd->ifd_len, KM_SLEEP); 257 1.39 pooka rv = copyinstr(ifd->ifd_data, sc->sc_linkstr, 258 1.39 pooka ifd->ifd_len, NULL); 259 1.39 pooka if (rv) { 260 1.39 pooka kmem_free(sc->sc_linkstr, ifd->ifd_len); 261 1.21 pooka break; 262 1.21 pooka } 263 1.21 pooka 264 1.39 pooka rv = virtif_create(ifp); 265 1.39 pooka if (rv) { 266 1.39 pooka kmem_free(sc->sc_linkstr, ifd->ifd_len); 267 1.39 pooka } 268 1.39 pooka break; 269 1.39 pooka #endif /* RUMP_VIF_LINKSTR */ 270 1.39 pooka default: 271 1.39 pooka if (!sc->sc_linkstr) 272 1.39 pooka rv = ENXIO; 273 1.39 pooka else 274 1.39 pooka rv = ether_ioctl(ifp, cmd, data); 275 1.39 pooka if (rv == ENETRESET) 276 1.39 pooka rv = 0; 277 1.39 pooka break; 278 1.1 pooka } 279 1.1 pooka 280 1.39 pooka return rv; 281 1.1 pooka } 282 1.8 pooka 283 1.39 pooka /* 284 1.39 pooka * Output packets in-context until outgoing queue is empty. 285 1.39 pooka * Leave responsibility of choosing whether or not to drop the 286 1.39 pooka * kernel lock to VIPHYPER_SEND(). 287 1.39 pooka */ 288 1.12 pooka #define LB_SH 32 289 1.8 pooka static void 290 1.39 pooka virtif_start(struct ifnet *ifp) 291 1.8 pooka { 292 1.8 pooka struct virtif_sc *sc = ifp->if_softc; 293 1.8 pooka struct mbuf *m, *m0; 294 1.30 pooka struct iovec io[LB_SH]; 295 1.30 pooka int i; 296 1.8 pooka 297 1.39 pooka ifp->if_flags |= IFF_OACTIVE; 298 1.39 pooka 299 1.39 pooka for (;;) { 300 1.8 pooka IF_DEQUEUE(&ifp->if_snd, m0); 301 1.8 pooka if (!m0) { 302 1.39 pooka break; 303 1.8 pooka } 304 1.8 pooka 305 1.8 pooka m = m0; 306 1.40 pooka for (i = 0; i < LB_SH && m; ) { 307 1.40 pooka if (m->m_len) { 308 1.40 pooka io[i].iov_base = mtod(m, void *); 309 1.40 pooka io[i].iov_len = m->m_len; 310 1.40 pooka i++; 311 1.40 pooka } 312 1.8 pooka m = m->m_next; 313 1.8 pooka } 314 1.40 pooka if (i == LB_SH && m) 315 1.8 pooka panic("lazy bum"); 316 1.57 msaitoh bpf_mtap(ifp, m0, BPF_D_OUT); 317 1.21 pooka 318 1.36 pooka VIFHYPER_SEND(sc->sc_viu, io, i); 319 1.21 pooka 320 1.8 pooka m_freem(m0); 321 1.58 thorpej if_statinc(ifp, if_opackets); 322 1.8 pooka } 323 1.21 pooka 324 1.39 pooka ifp->if_flags &= ~IFF_OACTIVE; 325 1.39 pooka } 326 1.39 pooka 327 1.39 pooka static void 328 1.39 pooka virtif_stop(struct ifnet *ifp, int disable) 329 1.39 pooka { 330 1.39 pooka 331 1.39 pooka /* XXX: VIFHYPER_STOP() */ 332 1.39 pooka 333 1.39 pooka ifp->if_flags &= ~IFF_RUNNING; 334 1.39 pooka } 335 1.39 pooka 336 1.39 pooka void 337 1.39 pooka VIF_DELIVERPKT(struct virtif_sc *sc, struct iovec *iov, size_t iovlen) 338 1.39 pooka { 339 1.39 pooka struct ifnet *ifp = &sc->sc_ec.ec_if; 340 1.39 pooka struct ether_header *eth; 341 1.39 pooka struct mbuf *m; 342 1.39 pooka size_t i; 343 1.39 pooka int off, olen; 344 1.39 pooka bool passup; 345 1.39 pooka const int align 346 1.39 pooka = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); 347 1.39 pooka 348 1.39 pooka if ((ifp->if_flags & IFF_RUNNING) == 0) 349 1.39 pooka return; 350 1.39 pooka 351 1.39 pooka m = m_gethdr(M_NOWAIT, MT_DATA); 352 1.39 pooka if (m == NULL) 353 1.39 pooka return; /* drop packet */ 354 1.39 pooka m->m_len = m->m_pkthdr.len = 0; 355 1.39 pooka 356 1.39 pooka for (i = 0, off = align; i < iovlen; i++) { 357 1.39 pooka olen = m->m_pkthdr.len; 358 1.39 pooka m_copyback(m, off, iov[i].iov_len, iov[i].iov_base); 359 1.39 pooka off += iov[i].iov_len; 360 1.39 pooka if (olen + off != m->m_pkthdr.len) { 361 1.39 pooka aprint_verbose_ifnet(ifp, "m_copyback failed\n"); 362 1.39 pooka m_freem(m); 363 1.39 pooka return; 364 1.39 pooka } 365 1.39 pooka } 366 1.45 pooka m->m_data += align; 367 1.45 pooka m->m_pkthdr.len -= align; 368 1.45 pooka m->m_len -= align; 369 1.39 pooka 370 1.39 pooka eth = mtod(m, struct ether_header *); 371 1.39 pooka if (memcmp(eth->ether_dhost, CLLADDR(ifp->if_sadl), 372 1.39 pooka ETHER_ADDR_LEN) == 0) { 373 1.39 pooka passup = true; 374 1.39 pooka } else if (ETHER_IS_MULTICAST(eth->ether_dhost)) { 375 1.39 pooka passup = true; 376 1.39 pooka } else if (ifp->if_flags & IFF_PROMISC) { 377 1.39 pooka m->m_flags |= M_PROMISC; 378 1.39 pooka passup = true; 379 1.39 pooka } else { 380 1.39 pooka passup = false; 381 1.39 pooka } 382 1.8 pooka 383 1.39 pooka if (passup) { 384 1.53 ozaki int bound; 385 1.52 ozaki m_set_rcvif(m, ifp); 386 1.39 pooka KERNEL_LOCK(1, NULL); 387 1.51 ozaki /* Prevent LWP migrations between CPUs for psref(9) */ 388 1.53 ozaki bound = curlwp_bind(); 389 1.50 ozaki if_input(ifp, m); 390 1.53 ozaki curlwp_bindx(bound); 391 1.39 pooka KERNEL_UNLOCK_LAST(NULL); 392 1.39 pooka } else { 393 1.39 pooka m_freem(m); 394 1.39 pooka } 395 1.39 pooka m = NULL; 396 1.8 pooka } 397 1.44 pooka 398 1.49 pooka /* 399 1.49 pooka * The following ensures that no two modules using if_virt end up with 400 1.49 pooka * the same module name. MODULE() and modcmd wrapped in ... bad mojo. 401 1.49 pooka */ 402 1.49 pooka #define VIF_MOJO(x) MODULE(MODULE_CLASS_DRIVER,x,NULL); 403 1.49 pooka #define VIF_MODULE() VIF_MOJO(VIF_BASENAME(if_virt_,VIRTIF_BASE)) 404 1.49 pooka #define VIF_MODCMD VIF_BASENAME3(if_virt_,VIRTIF_BASE,_modcmd) 405 1.49 pooka VIF_MODULE(); 406 1.44 pooka static int 407 1.49 pooka VIF_MODCMD(modcmd_t cmd, void *opaque) 408 1.44 pooka { 409 1.44 pooka int error = 0; 410 1.44 pooka 411 1.44 pooka switch (cmd) { 412 1.44 pooka case MODULE_CMD_INIT: 413 1.44 pooka if_clone_attach(&VIF_CLONER); 414 1.44 pooka break; 415 1.44 pooka case MODULE_CMD_FINI: 416 1.44 pooka /* 417 1.44 pooka * not sure if interfaces are refcounted 418 1.44 pooka * and properly protected 419 1.44 pooka */ 420 1.44 pooka #if 0 421 1.44 pooka if_clone_detach(&VIF_CLONER); 422 1.44 pooka #else 423 1.44 pooka error = ENOTTY; 424 1.44 pooka #endif 425 1.44 pooka break; 426 1.44 pooka default: 427 1.44 pooka error = ENOTTY; 428 1.44 pooka } 429 1.44 pooka return error; 430 1.44 pooka } 431