if_virt.c revision 1.45 1 1.45 pooka /* $NetBSD: if_virt.c,v 1.45 2014/03/18 18:10:08 pooka 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.45 pooka __KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.45 2014/03/18 18:10:08 pooka 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.36 pooka sprintf(ifp->if_xname, "%s%d", VIF_NAME, num);
113 1.1 pooka ifp->if_softc = sc;
114 1.21 pooka
115 1.1 pooka ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
116 1.1 pooka ifp->if_init = virtif_init;
117 1.1 pooka ifp->if_ioctl = virtif_ioctl;
118 1.1 pooka ifp->if_start = virtif_start;
119 1.1 pooka ifp->if_stop = virtif_stop;
120 1.39 pooka ifp->if_mtu = ETHERMTU;
121 1.39 pooka ifp->if_dlt = DLT_EN10MB;
122 1.1 pooka
123 1.1 pooka if_attach(ifp);
124 1.1 pooka
125 1.39 pooka #ifndef RUMP_VIF_LINKSTR
126 1.39 pooka /*
127 1.39 pooka * if the underlying interface does not expect linkstr, we can
128 1.39 pooka * create everything now. Otherwise, we need to wait for
129 1.39 pooka * SIOCSLINKSTR.
130 1.39 pooka */
131 1.39 pooka #define LINKSTRNUMLEN 16
132 1.39 pooka sc->sc_linkstr = kmem_alloc(LINKSTRNUMLEN, KM_SLEEP);
133 1.39 pooka snprintf(sc->sc_linkstr, LINKSTRNUMLEN, "%d", sc->sc_num);
134 1.39 pooka #undef LINKSTRNUMLEN
135 1.39 pooka error = virtif_create(ifp);
136 1.21 pooka if (error) {
137 1.39 pooka if_detach(ifp);
138 1.39 pooka kmem_free(sc, sizeof(*sc));
139 1.39 pooka ifp->if_softc = NULL;
140 1.21 pooka }
141 1.39 pooka #endif /* !RUMP_VIF_LINKSTR */
142 1.21 pooka
143 1.21 pooka return error;
144 1.1 pooka }
145 1.1 pooka
146 1.1 pooka static int
147 1.20 pooka virtif_unclone(struct ifnet *ifp)
148 1.20 pooka {
149 1.21 pooka struct virtif_sc *sc = ifp->if_softc;
150 1.42 pooka int rv;
151 1.20 pooka
152 1.39 pooka if (ifp->if_flags & IFF_UP)
153 1.39 pooka return EBUSY;
154 1.21 pooka
155 1.42 pooka if ((rv = VIFHYPER_DYING(sc->sc_viu)) != 0)
156 1.42 pooka return rv;
157 1.30 pooka
158 1.21 pooka virtif_stop(ifp, 1);
159 1.21 pooka if_down(ifp);
160 1.21 pooka
161 1.36 pooka VIFHYPER_DESTROY(sc->sc_viu);
162 1.21 pooka
163 1.21 pooka kmem_free(sc, sizeof(*sc));
164 1.21 pooka
165 1.21 pooka ether_ifdetach(ifp);
166 1.21 pooka if_detach(ifp);
167 1.21 pooka
168 1.21 pooka return 0;
169 1.20 pooka }
170 1.20 pooka
171 1.20 pooka static int
172 1.1 pooka virtif_init(struct ifnet *ifp)
173 1.1 pooka {
174 1.21 pooka struct virtif_sc *sc = ifp->if_softc;
175 1.1 pooka
176 1.39 pooka if (sc->sc_viu == NULL)
177 1.39 pooka return ENXIO;
178 1.39 pooka
179 1.1 pooka ifp->if_flags |= IFF_RUNNING;
180 1.1 pooka return 0;
181 1.1 pooka }
182 1.1 pooka
183 1.1 pooka static int
184 1.1 pooka virtif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
185 1.1 pooka {
186 1.39 pooka struct virtif_sc *sc = ifp->if_softc;
187 1.39 pooka int rv;
188 1.1 pooka
189 1.39 pooka switch (cmd) {
190 1.39 pooka #ifdef RUMP_VIF_LINKSTR
191 1.39 pooka struct ifdrv *ifd;
192 1.39 pooka size_t linkstrlen;
193 1.39 pooka
194 1.39 pooka #ifndef RUMP_VIF_LINKSTRMAX
195 1.39 pooka #define RUMP_VIF_LINKSTRMAX 4096
196 1.39 pooka #endif
197 1.1 pooka
198 1.39 pooka case SIOCGLINKSTR:
199 1.39 pooka ifd = data;
200 1.1 pooka
201 1.39 pooka if (!sc->sc_linkstr) {
202 1.39 pooka rv = ENOENT;
203 1.39 pooka break;
204 1.39 pooka }
205 1.39 pooka linkstrlen = strlen(sc->sc_linkstr)+1;
206 1.1 pooka
207 1.39 pooka if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) {
208 1.39 pooka ifd->ifd_len = linkstrlen;
209 1.39 pooka rv = 0;
210 1.39 pooka break;
211 1.39 pooka }
212 1.39 pooka if (ifd->ifd_cmd != 0) {
213 1.39 pooka rv = ENOTTY;
214 1.39 pooka break;
215 1.39 pooka }
216 1.1 pooka
217 1.39 pooka rv = copyoutstr(sc->sc_linkstr,
218 1.39 pooka ifd->ifd_data, MIN(ifd->ifd_len,linkstrlen), NULL);
219 1.39 pooka break;
220 1.39 pooka case SIOCSLINKSTR:
221 1.39 pooka if (ifp->if_flags & IFF_UP) {
222 1.39 pooka rv = EBUSY;
223 1.39 pooka break;
224 1.39 pooka }
225 1.1 pooka
226 1.39 pooka ifd = data;
227 1.21 pooka
228 1.39 pooka if (ifd->ifd_cmd == IFLINKSTR_UNSET) {
229 1.39 pooka panic("unset linkstr not implemented");
230 1.39 pooka } else if (ifd->ifd_cmd != 0) {
231 1.39 pooka rv = ENOTTY;
232 1.39 pooka break;
233 1.39 pooka } else if (sc->sc_linkstr) {
234 1.39 pooka rv = EBUSY;
235 1.39 pooka break;
236 1.39 pooka }
237 1.1 pooka
238 1.39 pooka if (ifd->ifd_len > RUMP_VIF_LINKSTRMAX) {
239 1.39 pooka rv = E2BIG;
240 1.39 pooka break;
241 1.39 pooka } else if (ifd->ifd_len < 1) {
242 1.39 pooka rv = EINVAL;
243 1.39 pooka break;
244 1.39 pooka }
245 1.21 pooka
246 1.1 pooka
247 1.39 pooka sc->sc_linkstr = kmem_alloc(ifd->ifd_len, KM_SLEEP);
248 1.39 pooka rv = copyinstr(ifd->ifd_data, sc->sc_linkstr,
249 1.39 pooka ifd->ifd_len, NULL);
250 1.39 pooka if (rv) {
251 1.39 pooka kmem_free(sc->sc_linkstr, ifd->ifd_len);
252 1.21 pooka break;
253 1.21 pooka }
254 1.21 pooka
255 1.39 pooka rv = virtif_create(ifp);
256 1.39 pooka if (rv) {
257 1.39 pooka kmem_free(sc->sc_linkstr, ifd->ifd_len);
258 1.39 pooka }
259 1.39 pooka break;
260 1.39 pooka #endif /* RUMP_VIF_LINKSTR */
261 1.39 pooka default:
262 1.39 pooka if (!sc->sc_linkstr)
263 1.39 pooka rv = ENXIO;
264 1.39 pooka else
265 1.39 pooka rv = ether_ioctl(ifp, cmd, data);
266 1.39 pooka if (rv == ENETRESET)
267 1.39 pooka rv = 0;
268 1.39 pooka break;
269 1.1 pooka }
270 1.1 pooka
271 1.39 pooka return rv;
272 1.1 pooka }
273 1.8 pooka
274 1.39 pooka /*
275 1.39 pooka * Output packets in-context until outgoing queue is empty.
276 1.39 pooka * Leave responsibility of choosing whether or not to drop the
277 1.39 pooka * kernel lock to VIPHYPER_SEND().
278 1.39 pooka */
279 1.12 pooka #define LB_SH 32
280 1.8 pooka static void
281 1.39 pooka virtif_start(struct ifnet *ifp)
282 1.8 pooka {
283 1.8 pooka struct virtif_sc *sc = ifp->if_softc;
284 1.8 pooka struct mbuf *m, *m0;
285 1.30 pooka struct iovec io[LB_SH];
286 1.30 pooka int i;
287 1.8 pooka
288 1.39 pooka ifp->if_flags |= IFF_OACTIVE;
289 1.39 pooka
290 1.39 pooka for (;;) {
291 1.8 pooka IF_DEQUEUE(&ifp->if_snd, m0);
292 1.8 pooka if (!m0) {
293 1.39 pooka break;
294 1.8 pooka }
295 1.8 pooka
296 1.8 pooka m = m0;
297 1.40 pooka for (i = 0; i < LB_SH && m; ) {
298 1.40 pooka if (m->m_len) {
299 1.40 pooka io[i].iov_base = mtod(m, void *);
300 1.40 pooka io[i].iov_len = m->m_len;
301 1.40 pooka i++;
302 1.40 pooka }
303 1.8 pooka m = m->m_next;
304 1.8 pooka }
305 1.40 pooka if (i == LB_SH && m)
306 1.8 pooka panic("lazy bum");
307 1.17 joerg bpf_mtap(ifp, m0);
308 1.21 pooka
309 1.36 pooka VIFHYPER_SEND(sc->sc_viu, io, i);
310 1.21 pooka
311 1.8 pooka m_freem(m0);
312 1.8 pooka }
313 1.21 pooka
314 1.39 pooka ifp->if_flags &= ~IFF_OACTIVE;
315 1.39 pooka }
316 1.39 pooka
317 1.39 pooka static void
318 1.39 pooka virtif_stop(struct ifnet *ifp, int disable)
319 1.39 pooka {
320 1.39 pooka
321 1.39 pooka /* XXX: VIFHYPER_STOP() */
322 1.39 pooka
323 1.39 pooka ifp->if_flags &= ~IFF_RUNNING;
324 1.39 pooka }
325 1.39 pooka
326 1.39 pooka void
327 1.39 pooka VIF_DELIVERPKT(struct virtif_sc *sc, struct iovec *iov, size_t iovlen)
328 1.39 pooka {
329 1.39 pooka struct ifnet *ifp = &sc->sc_ec.ec_if;
330 1.39 pooka struct ether_header *eth;
331 1.39 pooka struct mbuf *m;
332 1.39 pooka size_t i;
333 1.39 pooka int off, olen;
334 1.39 pooka bool passup;
335 1.39 pooka const int align
336 1.39 pooka = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
337 1.39 pooka
338 1.39 pooka if ((ifp->if_flags & IFF_RUNNING) == 0)
339 1.39 pooka return;
340 1.39 pooka
341 1.39 pooka m = m_gethdr(M_NOWAIT, MT_DATA);
342 1.39 pooka if (m == NULL)
343 1.39 pooka return; /* drop packet */
344 1.39 pooka m->m_len = m->m_pkthdr.len = 0;
345 1.39 pooka
346 1.39 pooka for (i = 0, off = align; i < iovlen; i++) {
347 1.39 pooka olen = m->m_pkthdr.len;
348 1.39 pooka m_copyback(m, off, iov[i].iov_len, iov[i].iov_base);
349 1.39 pooka off += iov[i].iov_len;
350 1.39 pooka if (olen + off != m->m_pkthdr.len) {
351 1.39 pooka aprint_verbose_ifnet(ifp, "m_copyback failed\n");
352 1.39 pooka m_freem(m);
353 1.39 pooka return;
354 1.39 pooka }
355 1.39 pooka }
356 1.45 pooka m->m_data += align;
357 1.45 pooka m->m_pkthdr.len -= align;
358 1.45 pooka m->m_len -= align;
359 1.39 pooka
360 1.39 pooka eth = mtod(m, struct ether_header *);
361 1.39 pooka if (memcmp(eth->ether_dhost, CLLADDR(ifp->if_sadl),
362 1.39 pooka ETHER_ADDR_LEN) == 0) {
363 1.39 pooka passup = true;
364 1.39 pooka } else if (ETHER_IS_MULTICAST(eth->ether_dhost)) {
365 1.39 pooka passup = true;
366 1.39 pooka } else if (ifp->if_flags & IFF_PROMISC) {
367 1.39 pooka m->m_flags |= M_PROMISC;
368 1.39 pooka passup = true;
369 1.39 pooka } else {
370 1.39 pooka passup = false;
371 1.39 pooka }
372 1.8 pooka
373 1.39 pooka if (passup) {
374 1.39 pooka m->m_pkthdr.rcvif = ifp;
375 1.39 pooka KERNEL_LOCK(1, NULL);
376 1.39 pooka bpf_mtap(ifp, m);
377 1.39 pooka ifp->if_input(ifp, m);
378 1.39 pooka KERNEL_UNLOCK_LAST(NULL);
379 1.39 pooka } else {
380 1.39 pooka m_freem(m);
381 1.39 pooka }
382 1.39 pooka m = NULL;
383 1.8 pooka }
384 1.44 pooka
385 1.44 pooka MODULE(MODULE_CLASS_DRIVER, if_virt, NULL);
386 1.44 pooka
387 1.44 pooka static int
388 1.44 pooka if_virt_modcmd(modcmd_t cmd, void *opaque)
389 1.44 pooka {
390 1.44 pooka int error = 0;
391 1.44 pooka
392 1.44 pooka switch (cmd) {
393 1.44 pooka case MODULE_CMD_INIT:
394 1.44 pooka if_clone_attach(&VIF_CLONER);
395 1.44 pooka break;
396 1.44 pooka case MODULE_CMD_FINI:
397 1.44 pooka /*
398 1.44 pooka * not sure if interfaces are refcounted
399 1.44 pooka * and properly protected
400 1.44 pooka */
401 1.44 pooka #if 0
402 1.44 pooka if_clone_detach(&VIF_CLONER);
403 1.44 pooka #else
404 1.44 pooka error = ENOTTY;
405 1.44 pooka #endif
406 1.44 pooka break;
407 1.44 pooka default:
408 1.44 pooka error = ENOTTY;
409 1.44 pooka }
410 1.44 pooka return error;
411 1.44 pooka }
412