if_virt.c revision 1.51 1 1.51 ozaki /* $NetBSD: if_virt.c,v 1.51 2016/04/19 05:48:10 ozaki-r 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.51 ozaki __KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.51 2016/04/19 05:48:10 ozaki-r 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.50 ozaki 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.39 pooka snprintf(sc->sc_linkstr, LINKSTRNUMLEN, "%d", sc->sc_num);
136 1.39 pooka #undef LINKSTRNUMLEN
137 1.39 pooka error = virtif_create(ifp);
138 1.21 pooka if (error) {
139 1.39 pooka if_detach(ifp);
140 1.39 pooka kmem_free(sc, sizeof(*sc));
141 1.39 pooka ifp->if_softc = NULL;
142 1.21 pooka }
143 1.39 pooka #endif /* !RUMP_VIF_LINKSTR */
144 1.21 pooka
145 1.21 pooka return error;
146 1.1 pooka }
147 1.1 pooka
148 1.1 pooka static int
149 1.20 pooka virtif_unclone(struct ifnet *ifp)
150 1.20 pooka {
151 1.21 pooka struct virtif_sc *sc = ifp->if_softc;
152 1.42 pooka int rv;
153 1.20 pooka
154 1.39 pooka if (ifp->if_flags & IFF_UP)
155 1.39 pooka return EBUSY;
156 1.21 pooka
157 1.42 pooka if ((rv = VIFHYPER_DYING(sc->sc_viu)) != 0)
158 1.42 pooka return rv;
159 1.30 pooka
160 1.21 pooka virtif_stop(ifp, 1);
161 1.21 pooka if_down(ifp);
162 1.21 pooka
163 1.36 pooka VIFHYPER_DESTROY(sc->sc_viu);
164 1.21 pooka
165 1.21 pooka kmem_free(sc, sizeof(*sc));
166 1.21 pooka
167 1.21 pooka ether_ifdetach(ifp);
168 1.21 pooka if_detach(ifp);
169 1.21 pooka
170 1.21 pooka return 0;
171 1.20 pooka }
172 1.20 pooka
173 1.20 pooka static int
174 1.1 pooka virtif_init(struct ifnet *ifp)
175 1.1 pooka {
176 1.21 pooka struct virtif_sc *sc = ifp->if_softc;
177 1.1 pooka
178 1.39 pooka if (sc->sc_viu == NULL)
179 1.39 pooka return ENXIO;
180 1.39 pooka
181 1.1 pooka ifp->if_flags |= IFF_RUNNING;
182 1.1 pooka return 0;
183 1.1 pooka }
184 1.1 pooka
185 1.1 pooka static int
186 1.1 pooka virtif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
187 1.1 pooka {
188 1.39 pooka struct virtif_sc *sc = ifp->if_softc;
189 1.39 pooka int rv;
190 1.1 pooka
191 1.39 pooka switch (cmd) {
192 1.39 pooka #ifdef RUMP_VIF_LINKSTR
193 1.39 pooka struct ifdrv *ifd;
194 1.39 pooka size_t linkstrlen;
195 1.39 pooka
196 1.39 pooka #ifndef RUMP_VIF_LINKSTRMAX
197 1.39 pooka #define RUMP_VIF_LINKSTRMAX 4096
198 1.39 pooka #endif
199 1.1 pooka
200 1.39 pooka case SIOCGLINKSTR:
201 1.39 pooka ifd = data;
202 1.1 pooka
203 1.39 pooka if (!sc->sc_linkstr) {
204 1.39 pooka rv = ENOENT;
205 1.39 pooka break;
206 1.39 pooka }
207 1.39 pooka linkstrlen = strlen(sc->sc_linkstr)+1;
208 1.1 pooka
209 1.39 pooka if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) {
210 1.39 pooka ifd->ifd_len = linkstrlen;
211 1.39 pooka rv = 0;
212 1.39 pooka break;
213 1.39 pooka }
214 1.39 pooka if (ifd->ifd_cmd != 0) {
215 1.39 pooka rv = ENOTTY;
216 1.39 pooka break;
217 1.39 pooka }
218 1.1 pooka
219 1.39 pooka rv = copyoutstr(sc->sc_linkstr,
220 1.39 pooka ifd->ifd_data, MIN(ifd->ifd_len,linkstrlen), NULL);
221 1.39 pooka break;
222 1.39 pooka case SIOCSLINKSTR:
223 1.39 pooka if (ifp->if_flags & IFF_UP) {
224 1.39 pooka rv = EBUSY;
225 1.39 pooka break;
226 1.39 pooka }
227 1.1 pooka
228 1.39 pooka ifd = data;
229 1.21 pooka
230 1.39 pooka if (ifd->ifd_cmd == IFLINKSTR_UNSET) {
231 1.39 pooka panic("unset linkstr not implemented");
232 1.39 pooka } else if (ifd->ifd_cmd != 0) {
233 1.39 pooka rv = ENOTTY;
234 1.39 pooka break;
235 1.39 pooka } else if (sc->sc_linkstr) {
236 1.39 pooka rv = EBUSY;
237 1.39 pooka break;
238 1.39 pooka }
239 1.1 pooka
240 1.39 pooka if (ifd->ifd_len > RUMP_VIF_LINKSTRMAX) {
241 1.39 pooka rv = E2BIG;
242 1.39 pooka break;
243 1.39 pooka } else if (ifd->ifd_len < 1) {
244 1.39 pooka rv = EINVAL;
245 1.39 pooka break;
246 1.39 pooka }
247 1.21 pooka
248 1.1 pooka
249 1.39 pooka sc->sc_linkstr = kmem_alloc(ifd->ifd_len, KM_SLEEP);
250 1.39 pooka rv = copyinstr(ifd->ifd_data, sc->sc_linkstr,
251 1.39 pooka ifd->ifd_len, NULL);
252 1.39 pooka if (rv) {
253 1.39 pooka kmem_free(sc->sc_linkstr, ifd->ifd_len);
254 1.21 pooka break;
255 1.21 pooka }
256 1.21 pooka
257 1.39 pooka rv = virtif_create(ifp);
258 1.39 pooka if (rv) {
259 1.39 pooka kmem_free(sc->sc_linkstr, ifd->ifd_len);
260 1.39 pooka }
261 1.39 pooka break;
262 1.39 pooka #endif /* RUMP_VIF_LINKSTR */
263 1.39 pooka default:
264 1.39 pooka if (!sc->sc_linkstr)
265 1.39 pooka rv = ENXIO;
266 1.39 pooka else
267 1.39 pooka rv = ether_ioctl(ifp, cmd, data);
268 1.39 pooka if (rv == ENETRESET)
269 1.39 pooka rv = 0;
270 1.39 pooka break;
271 1.1 pooka }
272 1.1 pooka
273 1.39 pooka return rv;
274 1.1 pooka }
275 1.8 pooka
276 1.39 pooka /*
277 1.39 pooka * Output packets in-context until outgoing queue is empty.
278 1.39 pooka * Leave responsibility of choosing whether or not to drop the
279 1.39 pooka * kernel lock to VIPHYPER_SEND().
280 1.39 pooka */
281 1.12 pooka #define LB_SH 32
282 1.8 pooka static void
283 1.39 pooka virtif_start(struct ifnet *ifp)
284 1.8 pooka {
285 1.8 pooka struct virtif_sc *sc = ifp->if_softc;
286 1.8 pooka struct mbuf *m, *m0;
287 1.30 pooka struct iovec io[LB_SH];
288 1.30 pooka int i;
289 1.8 pooka
290 1.39 pooka ifp->if_flags |= IFF_OACTIVE;
291 1.39 pooka
292 1.39 pooka for (;;) {
293 1.8 pooka IF_DEQUEUE(&ifp->if_snd, m0);
294 1.8 pooka if (!m0) {
295 1.39 pooka break;
296 1.8 pooka }
297 1.8 pooka
298 1.8 pooka m = m0;
299 1.40 pooka for (i = 0; i < LB_SH && m; ) {
300 1.40 pooka if (m->m_len) {
301 1.40 pooka io[i].iov_base = mtod(m, void *);
302 1.40 pooka io[i].iov_len = m->m_len;
303 1.40 pooka i++;
304 1.40 pooka }
305 1.8 pooka m = m->m_next;
306 1.8 pooka }
307 1.40 pooka if (i == LB_SH && m)
308 1.8 pooka panic("lazy bum");
309 1.17 joerg bpf_mtap(ifp, m0);
310 1.21 pooka
311 1.36 pooka VIFHYPER_SEND(sc->sc_viu, io, i);
312 1.21 pooka
313 1.8 pooka m_freem(m0);
314 1.48 ozaki ifp->if_opackets++;
315 1.8 pooka }
316 1.21 pooka
317 1.39 pooka ifp->if_flags &= ~IFF_OACTIVE;
318 1.39 pooka }
319 1.39 pooka
320 1.39 pooka static void
321 1.39 pooka virtif_stop(struct ifnet *ifp, int disable)
322 1.39 pooka {
323 1.39 pooka
324 1.39 pooka /* XXX: VIFHYPER_STOP() */
325 1.39 pooka
326 1.39 pooka ifp->if_flags &= ~IFF_RUNNING;
327 1.39 pooka }
328 1.39 pooka
329 1.39 pooka void
330 1.39 pooka VIF_DELIVERPKT(struct virtif_sc *sc, struct iovec *iov, size_t iovlen)
331 1.39 pooka {
332 1.39 pooka struct ifnet *ifp = &sc->sc_ec.ec_if;
333 1.39 pooka struct ether_header *eth;
334 1.39 pooka struct mbuf *m;
335 1.39 pooka size_t i;
336 1.39 pooka int off, olen;
337 1.39 pooka bool passup;
338 1.39 pooka const int align
339 1.39 pooka = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
340 1.39 pooka
341 1.39 pooka if ((ifp->if_flags & IFF_RUNNING) == 0)
342 1.39 pooka return;
343 1.39 pooka
344 1.39 pooka m = m_gethdr(M_NOWAIT, MT_DATA);
345 1.39 pooka if (m == NULL)
346 1.39 pooka return; /* drop packet */
347 1.39 pooka m->m_len = m->m_pkthdr.len = 0;
348 1.39 pooka
349 1.39 pooka for (i = 0, off = align; i < iovlen; i++) {
350 1.39 pooka olen = m->m_pkthdr.len;
351 1.39 pooka m_copyback(m, off, iov[i].iov_len, iov[i].iov_base);
352 1.39 pooka off += iov[i].iov_len;
353 1.39 pooka if (olen + off != m->m_pkthdr.len) {
354 1.39 pooka aprint_verbose_ifnet(ifp, "m_copyback failed\n");
355 1.39 pooka m_freem(m);
356 1.39 pooka return;
357 1.39 pooka }
358 1.39 pooka }
359 1.45 pooka m->m_data += align;
360 1.45 pooka m->m_pkthdr.len -= align;
361 1.45 pooka m->m_len -= align;
362 1.39 pooka
363 1.39 pooka eth = mtod(m, struct ether_header *);
364 1.39 pooka if (memcmp(eth->ether_dhost, CLLADDR(ifp->if_sadl),
365 1.39 pooka ETHER_ADDR_LEN) == 0) {
366 1.39 pooka passup = true;
367 1.39 pooka } else if (ETHER_IS_MULTICAST(eth->ether_dhost)) {
368 1.39 pooka passup = true;
369 1.39 pooka } else if (ifp->if_flags & IFF_PROMISC) {
370 1.39 pooka m->m_flags |= M_PROMISC;
371 1.39 pooka passup = true;
372 1.39 pooka } else {
373 1.39 pooka passup = false;
374 1.39 pooka }
375 1.8 pooka
376 1.39 pooka if (passup) {
377 1.51 ozaki int bound = curlwp->l_pflag & LP_BOUND;
378 1.48 ozaki ifp->if_ipackets++;
379 1.39 pooka m->m_pkthdr.rcvif = ifp;
380 1.39 pooka KERNEL_LOCK(1, NULL);
381 1.51 ozaki /* Prevent LWP migrations between CPUs for psref(9) */
382 1.51 ozaki curlwp->l_pflag |= LP_BOUND;
383 1.39 pooka bpf_mtap(ifp, m);
384 1.50 ozaki if_input(ifp, m);
385 1.51 ozaki curlwp->l_pflag ^= bound ^ LP_BOUND;
386 1.39 pooka KERNEL_UNLOCK_LAST(NULL);
387 1.39 pooka } else {
388 1.39 pooka m_freem(m);
389 1.39 pooka }
390 1.39 pooka m = NULL;
391 1.8 pooka }
392 1.44 pooka
393 1.49 pooka /*
394 1.49 pooka * The following ensures that no two modules using if_virt end up with
395 1.49 pooka * the same module name. MODULE() and modcmd wrapped in ... bad mojo.
396 1.49 pooka */
397 1.49 pooka #define VIF_MOJO(x) MODULE(MODULE_CLASS_DRIVER,x,NULL);
398 1.49 pooka #define VIF_MODULE() VIF_MOJO(VIF_BASENAME(if_virt_,VIRTIF_BASE))
399 1.49 pooka #define VIF_MODCMD VIF_BASENAME3(if_virt_,VIRTIF_BASE,_modcmd)
400 1.49 pooka VIF_MODULE();
401 1.44 pooka static int
402 1.49 pooka VIF_MODCMD(modcmd_t cmd, void *opaque)
403 1.44 pooka {
404 1.44 pooka int error = 0;
405 1.44 pooka
406 1.44 pooka switch (cmd) {
407 1.44 pooka case MODULE_CMD_INIT:
408 1.44 pooka if_clone_attach(&VIF_CLONER);
409 1.44 pooka break;
410 1.44 pooka case MODULE_CMD_FINI:
411 1.44 pooka /*
412 1.44 pooka * not sure if interfaces are refcounted
413 1.44 pooka * and properly protected
414 1.44 pooka */
415 1.44 pooka #if 0
416 1.44 pooka if_clone_detach(&VIF_CLONER);
417 1.44 pooka #else
418 1.44 pooka error = ENOTTY;
419 1.44 pooka #endif
420 1.44 pooka break;
421 1.44 pooka default:
422 1.44 pooka error = ENOTTY;
423 1.44 pooka }
424 1.44 pooka return error;
425 1.44 pooka }
426