FreeBSD/Linux Kernel Cross Reference
sys/net/if_gre.c
1 /* $NetBSD: if_gre.c,v 1.138 2008/08/06 15:01:23 plunky Exp $ */
2
3 /*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Heiko W.Rupp <hwr@pilhuhn.de>
9 *
10 * IPv6-over-GRE contributed by Gert Doering <gert@greenie.muc.de>
11 *
12 * GRE over UDP/IPv4/IPv6 sockets contributed by David Young <dyoung@NetBSD.org>
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * This material is based upon work partially supported by NSF
36 * under Contract No. NSF CNS-0626584.
37 */
38
39 /*
40 * Encapsulate L3 protocols into IP
41 * See RFC 1701 and 1702 for more details.
42 * If_gre is compatible with Cisco GRE tunnels, so you can
43 * have a NetBSD box as the other end of a tunnel interface of a Cisco
44 * router. See gre(4) for more details.
45 */
46
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.138 2008/08/06 15:01:23 plunky Exp $");
49
50 #include "opt_gre.h"
51 #include "opt_inet.h"
52 #include "bpfilter.h"
53
54 #ifdef INET
55 #include <sys/param.h>
56 #include <sys/file.h>
57 #include <sys/filedesc.h>
58 #include <sys/malloc.h>
59 #include <sys/mallocvar.h>
60 #include <sys/mbuf.h>
61 #include <sys/proc.h>
62 #include <sys/domain.h>
63 #include <sys/protosw.h>
64 #include <sys/socket.h>
65 #include <sys/socketvar.h>
66 #include <sys/ioctl.h>
67 #include <sys/queue.h>
68 #include <sys/intr.h>
69 #if __NetBSD__
70 #include <sys/systm.h>
71 #include <sys/sysctl.h>
72 #include <sys/kauth.h>
73 #endif
74
75 #include <sys/kernel.h>
76 #include <sys/mutex.h>
77 #include <sys/condvar.h>
78 #include <sys/kthread.h>
79
80 #include <sys/cpu.h>
81
82 #include <net/ethertypes.h>
83 #include <net/if.h>
84 #include <net/if_types.h>
85 #include <net/netisr.h>
86 #include <net/route.h>
87
88 #ifdef INET
89 #include <netinet/in.h>
90 #include <netinet/in_systm.h>
91 #include <netinet/in_var.h>
92 #include <netinet/ip.h>
93 #include <netinet/ip_var.h>
94 #else
95 #error "Huh? if_gre without inet?"
96 #endif
97
98
99 #ifdef NETATALK
100 #include <netatalk/at.h>
101 #include <netatalk/at_var.h>
102 #include <netatalk/at_extern.h>
103 #endif
104
105 #if NBPFILTER > 0
106 #include <sys/time.h>
107 #include <net/bpf.h>
108 #endif
109
110 #include <net/if_gre.h>
111
112 #include <compat/sys/socket.h>
113 #include <compat/sys/sockio.h>
114 /*
115 * It is not easy to calculate the right value for a GRE MTU.
116 * We leave this task to the admin and use the same default that
117 * other vendors use.
118 */
119 #define GREMTU 1476
120
121 #ifdef GRE_DEBUG
122 int gre_debug = 0;
123 #define GRE_DPRINTF(__sc, ...) \
124 do { \
125 if (__predict_false(gre_debug || \
126 ((__sc)->sc_if.if_flags & IFF_DEBUG) != 0)) { \
127 printf("%s.%d: ", __func__, __LINE__); \
128 printf(__VA_ARGS__); \
129 } \
130 } while (/*CONSTCOND*/0)
131 #else
132 #define GRE_DPRINTF(__sc, __fmt, ...) do { } while (/*CONSTCOND*/0)
133 #endif /* GRE_DEBUG */
134
135 int ip_gre_ttl = GRE_TTL;
136 MALLOC_DEFINE(M_GRE_BUFQ, "gre_bufq", "gre mbuf queue");
137
138 static int gre_clone_create(struct if_clone *, int);
139 static int gre_clone_destroy(struct ifnet *);
140
141 static struct if_clone gre_cloner =
142 IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy);
143
144 static int gre_input(struct gre_softc *, struct mbuf *, int,
145 const struct gre_h *);
146 static bool gre_is_nullconf(const struct gre_soparm *);
147 static int gre_output(struct ifnet *, struct mbuf *,
148 const struct sockaddr *, struct rtentry *);
149 static int gre_ioctl(struct ifnet *, u_long, void *);
150 static int gre_getsockname(struct socket *, struct mbuf *, struct lwp *);
151 static int gre_getpeername(struct socket *, struct mbuf *, struct lwp *);
152 static int gre_getnames(struct socket *, struct lwp *,
153 struct sockaddr_storage *, struct sockaddr_storage *);
154 static void gre_clearconf(struct gre_soparm *, bool);
155 static int gre_soreceive(struct socket *, struct mbuf **);
156 static int gre_sosend(struct socket *, struct mbuf *);
157 static struct socket *gre_reconf(struct gre_softc *, const struct gre_soparm *);
158
159 static bool gre_fp_send(struct gre_softc *, enum gre_msg, file_t *);
160 static bool gre_fp_recv(struct gre_softc *);
161 static void gre_fp_recvloop(void *);
162
163 static int
164 nearest_pow2(size_t len0)
165 {
166 size_t len, mid;
167
168 if (len0 == 0)
169 return 1;
170
171 for (len = len0; (len & (len - 1)) != 0; len &= len - 1)
172 ;
173
174 mid = len | (len >> 1);
175
176 /* avoid overflow */
177 if ((len << 1) < len)
178 return len;
179 if (len0 >= mid)
180 return len << 1;
181 return len;
182 }
183
184 static struct gre_bufq *
185 gre_bufq_init(struct gre_bufq *bq, size_t len0)
186 {
187 size_t len;
188
189 len = nearest_pow2(len0);
190
191 memset(bq, 0, sizeof(*bq));
192 bq->bq_buf = malloc(len * sizeof(struct mbuf *), M_GRE_BUFQ, M_WAITOK);
193 bq->bq_len = len;
194 bq->bq_lenmask = len - 1;
195
196 return bq;
197 }
198
199 static bool
200 gre_bufq_empty(struct gre_bufq *bq)
201 {
202 return bq->bq_prodidx == bq->bq_considx;
203 }
204
205 static struct mbuf *
206 gre_bufq_dequeue(struct gre_bufq *bq)
207 {
208 struct mbuf *m;
209
210 if (gre_bufq_empty(bq))
211 return NULL;
212
213 m = bq->bq_buf[bq->bq_considx];
214 bq->bq_considx = (bq->bq_considx + 1) & bq->bq_lenmask;
215
216 return m;
217 }
218
219 static void
220 gre_bufq_purge(struct gre_bufq *bq)
221 {
222 struct mbuf *m;
223
224 while ((m = gre_bufq_dequeue(bq)) != NULL)
225 m_freem(m);
226 }
227
228 static int
229 gre_bufq_enqueue(struct gre_bufq *bq, struct mbuf *m)
230 {
231 int next;
232
233 next = (bq->bq_prodidx + 1) & bq->bq_lenmask;
234
235 if (next == bq->bq_considx) {
236 bq->bq_drops++;
237 return ENOBUFS;
238 }
239
240 bq->bq_buf[bq->bq_prodidx] = m;
241 bq->bq_prodidx = next;
242 return 0;
243 }
244
245 static void
246 greintr(void *arg)
247 {
248 struct gre_softc *sc = (struct gre_softc *)arg;
249 struct socket *so = sc->sc_soparm.sp_so;
250 int rc;
251 struct mbuf *m;
252
253 KASSERT(so != NULL);
254
255 sc->sc_send_ev.ev_count++;
256 GRE_DPRINTF(sc, "enter\n");
257 while ((m = gre_bufq_dequeue(&sc->sc_snd)) != NULL) {
258 /* XXX handle ENOBUFS? */
259 if ((rc = gre_sosend(so, m)) != 0)
260 GRE_DPRINTF(sc, "gre_sosend failed %d\n", rc);
261 }
262 }
263
264 /* Caller must hold sc->sc_mtx. */
265 static void
266 gre_wait(struct gre_softc *sc)
267 {
268 sc->sc_waiters++;
269 cv_wait(&sc->sc_condvar, &sc->sc_mtx);
270 sc->sc_waiters--;
271 }
272
273 static void
274 gre_fp_wait(struct gre_softc *sc)
275 {
276 sc->sc_fp_waiters++;
277 cv_wait(&sc->sc_fp_condvar, &sc->sc_mtx);
278 sc->sc_fp_waiters--;
279 }
280
281 static void
282 gre_evcnt_detach(struct gre_softc *sc)
283 {
284 evcnt_detach(&sc->sc_unsupp_ev);
285 evcnt_detach(&sc->sc_pullup_ev);
286 evcnt_detach(&sc->sc_error_ev);
287 evcnt_detach(&sc->sc_block_ev);
288 evcnt_detach(&sc->sc_recv_ev);
289
290 evcnt_detach(&sc->sc_oflow_ev);
291 evcnt_detach(&sc->sc_send_ev);
292 }
293
294 static void
295 gre_evcnt_attach(struct gre_softc *sc)
296 {
297 evcnt_attach_dynamic(&sc->sc_recv_ev, EVCNT_TYPE_MISC,
298 NULL, sc->sc_if.if_xname, "recv");
299 evcnt_attach_dynamic(&sc->sc_block_ev, EVCNT_TYPE_MISC,
300 &sc->sc_recv_ev, sc->sc_if.if_xname, "would block");
301 evcnt_attach_dynamic(&sc->sc_error_ev, EVCNT_TYPE_MISC,
302 &sc->sc_recv_ev, sc->sc_if.if_xname, "error");
303 evcnt_attach_dynamic(&sc->sc_pullup_ev, EVCNT_TYPE_MISC,
304 &sc->sc_recv_ev, sc->sc_if.if_xname, "pullup failed");
305 evcnt_attach_dynamic(&sc->sc_unsupp_ev, EVCNT_TYPE_MISC,
306 &sc->sc_recv_ev, sc->sc_if.if_xname, "unsupported");
307
308 evcnt_attach_dynamic(&sc->sc_send_ev, EVCNT_TYPE_MISC,
309 NULL, sc->sc_if.if_xname, "send");
310 evcnt_attach_dynamic(&sc->sc_oflow_ev, EVCNT_TYPE_MISC,
311 &sc->sc_send_ev, sc->sc_if.if_xname, "overflow");
312 }
313
314 static int
315 gre_clone_create(struct if_clone *ifc, int unit)
316 {
317 int rc;
318 struct gre_softc *sc;
319 struct gre_soparm *sp;
320
321 sc = malloc(sizeof(struct gre_softc), M_DEVBUF, M_WAITOK|M_ZERO);
322 mutex_init(&sc->sc_mtx, MUTEX_DRIVER, IPL_SOFTNET);
323 cv_init(&sc->sc_condvar, "gre wait");
324 cv_init(&sc->sc_fp_condvar, "gre fp");
325
326 if_initname(&sc->sc_if, ifc->ifc_name, unit);
327 sc->sc_if.if_softc = sc;
328 sc->sc_if.if_type = IFT_TUNNEL;
329 sc->sc_if.if_addrlen = 0;
330 sc->sc_if.if_hdrlen = sizeof(struct ip) + sizeof(struct gre_h);
331 sc->sc_if.if_dlt = DLT_NULL;
332 sc->sc_if.if_mtu = GREMTU;
333 sc->sc_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
334 sc->sc_if.if_output = gre_output;
335 sc->sc_if.if_ioctl = gre_ioctl;
336 sp = &sc->sc_soparm;
337 sockaddr_copy(sstosa(&sp->sp_dst), sizeof(sp->sp_dst),
338 sintocsa(&in_any));
339 sockaddr_copy(sstosa(&sp->sp_src), sizeof(sp->sp_src),
340 sintocsa(&in_any));
341 sp->sp_proto = IPPROTO_GRE;
342 sp->sp_type = SOCK_RAW;
343
344 sc->sc_fd = -1;
345
346 rc = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, gre_fp_recvloop, sc,
347 NULL, sc->sc_if.if_xname);
348
349 if (rc != 0)
350 return -1;
351
352 gre_evcnt_attach(sc);
353
354 gre_bufq_init(&sc->sc_snd, 17);
355 sc->sc_if.if_flags |= IFF_LINK0;
356 if_attach(&sc->sc_if);
357 if_alloc_sadl(&sc->sc_if);
358 #if NBPFILTER > 0
359 bpfattach(&sc->sc_if, DLT_NULL, sizeof(uint32_t));
360 #endif
361 sc->sc_state = GRE_S_IDLE;
362 return 0;
363 }
364
365 static int
366 gre_clone_destroy(struct ifnet *ifp)
367 {
368 int s;
369 struct gre_softc *sc = ifp->if_softc;
370
371 GRE_DPRINTF(sc, "\n");
372
373 #if NBPFILTER > 0
374 bpfdetach(ifp);
375 #endif
376 s = splnet();
377 if_detach(ifp);
378
379 /* Some LWPs may still wait in gre_ioctl_lock(), however,
380 * no new LWP will enter gre_ioctl_lock(), because ifunit()
381 * cannot locate the interface any longer.
382 */
383 mutex_enter(&sc->sc_mtx);
384 GRE_DPRINTF(sc, "\n");
385 while (sc->sc_state != GRE_S_IDLE)
386 gre_wait(sc);
387 GRE_DPRINTF(sc, "\n");
388 sc->sc_state = GRE_S_DIE;
389 cv_broadcast(&sc->sc_condvar);
390 while (sc->sc_waiters > 0)
391 cv_wait(&sc->sc_condvar, &sc->sc_mtx);
392 /* At this point, no other LWP will access the gre_softc, so
393 * we can release the mutex.
394 */
395 mutex_exit(&sc->sc_mtx);
396 GRE_DPRINTF(sc, "\n");
397 /* Note that we must not hold the mutex while we call gre_reconf(). */
398 gre_reconf(sc, NULL);
399
400 mutex_enter(&sc->sc_mtx);
401 sc->sc_msg = GRE_M_STOP;
402 cv_signal(&sc->sc_fp_condvar);
403 while (sc->sc_fp_waiters > 0)
404 cv_wait(&sc->sc_fp_condvar, &sc->sc_mtx);
405 mutex_exit(&sc->sc_mtx);
406
407 splx(s);
408
409 cv_destroy(&sc->sc_condvar);
410 cv_destroy(&sc->sc_fp_condvar);
411 mutex_destroy(&sc->sc_mtx);
412 gre_evcnt_detach(sc);
413 free(sc, M_DEVBUF);
414
415 return 0;
416 }
417
418 static void
419 gre_receive(struct socket *so, void *arg, int waitflag)
420 {
421 struct gre_softc *sc = (struct gre_softc *)arg;
422 int rc;
423 const struct gre_h *gh;
424 struct mbuf *m;
425
426 GRE_DPRINTF(sc, "enter\n");
427
428 sc->sc_recv_ev.ev_count++;
429
430 rc = gre_soreceive(so, &m);
431 /* TBD Back off if ECONNREFUSED (indicates
432 * ICMP Port Unreachable)?
433 */
434 if (rc == EWOULDBLOCK) {
435 GRE_DPRINTF(sc, "EWOULDBLOCK\n");
436 sc->sc_block_ev.ev_count++;
437 return;
438 } else if (rc != 0 || m == NULL) {
439 GRE_DPRINTF(sc, "%s: rc %d m %p\n",
440 sc->sc_if.if_xname, rc, (void *)m);
441 sc->sc_error_ev.ev_count++;
442 return;
443 }
444 if (m->m_len < sizeof(*gh) && (m = m_pullup(m, sizeof(*gh))) == NULL) {
445 GRE_DPRINTF(sc, "m_pullup failed\n");
446 sc->sc_pullup_ev.ev_count++;
447 return;
448 }
449 gh = mtod(m, const struct gre_h *);
450
451 if (gre_input(sc, m, 0, gh) == 0) {
452 sc->sc_unsupp_ev.ev_count++;
453 GRE_DPRINTF(sc, "dropping unsupported\n");
454 m_freem(m);
455 }
456 }
457
458 static void
459 gre_upcall_add(struct socket *so, void *arg)
460 {
461 /* XXX What if the kernel already set an upcall? */
462 KASSERT((so->so_rcv.sb_flags & SB_UPCALL) == 0);
463 so->so_upcallarg = arg;
464 so->so_upcall = gre_receive;
465 so->so_rcv.sb_flags |= SB_UPCALL;
466 }
467
468 static void
469 gre_upcall_remove(struct socket *so)
470 {
471 so->so_rcv.sb_flags &= ~SB_UPCALL;
472 so->so_upcallarg = NULL;
473 so->so_upcall = NULL;
474 }
475
476 static int
477 gre_socreate(struct gre_softc *sc, const struct gre_soparm *sp, int *fdout)
478 {
479 const struct protosw *pr;
480 int fd, rc;
481 struct mbuf *m;
482 struct sockaddr *sa;
483 struct socket *so;
484 sa_family_t af;
485 int val;
486
487 GRE_DPRINTF(sc, "enter\n");
488
489 af = sp->sp_src.ss_family;
490 rc = fsocreate(af, NULL, sp->sp_type, sp->sp_proto, curlwp, &fd);
491 if (rc != 0) {
492 GRE_DPRINTF(sc, "fsocreate failed\n");
493 return rc;
494 }
495
496 if ((rc = fd_getsock(fd, &so)) != 0)
497 return rc;
498
499 if ((m = getsombuf(so, MT_SONAME)) == NULL) {
500 rc = ENOBUFS;
501 goto out;
502 }
503 sa = mtod(m, struct sockaddr *);
504 sockaddr_copy(sa, MIN(MLEN, sizeof(sp->sp_src)), sstocsa(&sp->sp_src));
505 m->m_len = sp->sp_src.ss_len;
506
507 if ((rc = sobind(so, m, curlwp)) != 0) {
508 GRE_DPRINTF(sc, "sobind failed\n");
509 goto out;
510 }
511
512 sockaddr_copy(sa, MIN(MLEN, sizeof(sp->sp_dst)), sstocsa(&sp->sp_dst));
513 m->m_len = sp->sp_dst.ss_len;
514
515 solock(so);
516 if ((rc = soconnect(so, m, curlwp)) != 0) {
517 GRE_DPRINTF(sc, "soconnect failed\n");
518 sounlock(so);
519 goto out;
520 }
521 sounlock(so);
522
523 m = NULL;
524
525 /* XXX convert to a (new) SOL_SOCKET call */
526 pr = so->so_proto;
527 KASSERT(pr != NULL);
528 rc = so_setsockopt(curlwp, so, IPPROTO_IP, IP_TTL,
529 &ip_gre_ttl, sizeof(ip_gre_ttl));
530 if (rc != 0) {
531 GRE_DPRINTF(sc, "so_setsockopt ttl failed\n");
532 rc = 0;
533 }
534 val = 1;
535 rc = so_setsockopt(curlwp, so, SOL_SOCKET, SO_NOHEADER,
536 &val, sizeof(val));
537 if (rc != 0) {
538 GRE_DPRINTF(sc, "so_setsockopt SO_NOHEADER failed\n");
539 rc = 0;
540 }
541 out:
542 m_freem(m);
543
544 if (rc != 0)
545 fd_close(fd);
546 else {
547 fd_putfile(fd);
548 *fdout = fd;
549 }
550
551 return rc;
552 }
553
554 static int
555 gre_sosend(struct socket *so, struct mbuf *top)
556 {
557 struct mbuf **mp;
558 struct proc *p;
559 long space, resid;
560 int error;
561 struct lwp * const l = curlwp;
562
563 p = l->l_proc;
564
565 resid = top->m_pkthdr.len;
566 if (p)
567 l->l_ru.ru_msgsnd++;
568 #define snderr(errno) { error = errno; goto release; }
569
570 solock(so);
571 if ((error = sblock(&so->so_snd, M_NOWAIT)) != 0)
572 goto out;
573 if (so->so_state & SS_CANTSENDMORE)
574 snderr(EPIPE);
575 if (so->so_error) {
576 error = so->so_error;
577 so->so_error = 0;
578 goto release;
579 }
580 if ((so->so_state & SS_ISCONNECTED) == 0) {
581 if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
582 if ((so->so_state & SS_ISCONFIRMING) == 0)
583 snderr(ENOTCONN);
584 } else
585 snderr(EDESTADDRREQ);
586 }
587 space = sbspace(&so->so_snd);
588 if (resid > so->so_snd.sb_hiwat)
589 snderr(EMSGSIZE);
590 if (space < resid)
591 snderr(EWOULDBLOCK);
592 mp = ⊤
593 /*
594 * Data is prepackaged in "top".
595 */
596 if (so->so_state & SS_CANTSENDMORE)
597 snderr(EPIPE);
598 error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, NULL, NULL, l);
599 top = NULL;
600 mp = ⊤
601 release:
602 sbunlock(&so->so_snd);
603 out:
604 sounlock(so);
605 if (top != NULL)
606 m_freem(top);
607 return error;
608 }
609
610 /* This is a stripped-down version of soreceive() that will never
611 * block. It will support SOCK_DGRAM sockets. It may also support
612 * SOCK_SEQPACKET sockets.
613 */
614 static int
615 gre_soreceive(struct socket *so, struct mbuf **mp0)
616 {
617 struct mbuf *m, **mp;
618 int flags, len, error, type;
619 const struct protosw *pr;
620 struct mbuf *nextrecord;
621
622 KASSERT(mp0 != NULL);
623
624 flags = MSG_DONTWAIT;
625 pr = so->so_proto;
626 mp = mp0;
627 type = 0;
628
629 *mp = NULL;
630
631 KASSERT(pr->pr_flags & PR_ATOMIC);
632
633 if (so->so_state & SS_ISCONFIRMING)
634 (*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, curlwp);
635 restart:
636 if ((error = sblock(&so->so_rcv, M_NOWAIT)) != 0) {
637 return error;
638 }
639 m = so->so_rcv.sb_mb;
640 /*
641 * If we have less data than requested, do not block awaiting more.
642 */
643 if (m == NULL) {
644 #ifdef DIAGNOSTIC
645 if (so->so_rcv.sb_cc)
646 panic("receive 1");
647 #endif
648 if (so->so_error) {
649 error = so->so_error;
650 so->so_error = 0;
651 } else if (so->so_state & SS_CANTRCVMORE)
652 ;
653 else if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0
654 && (so->so_proto->pr_flags & PR_CONNREQUIRED))
655 error = ENOTCONN;
656 else
657 error = EWOULDBLOCK;
658 goto release;
659 }
660 /*
661 * On entry here, m points to the first record of the socket buffer.
662 * While we process the initial mbufs containing address and control
663 * info, we save a copy of m->m_nextpkt into nextrecord.
664 */
665 if (curlwp != NULL)
666 curlwp->l_ru.ru_msgrcv++;
667 KASSERT(m == so->so_rcv.sb_mb);
668 SBLASTRECORDCHK(&so->so_rcv, "soreceive 1");
669 SBLASTMBUFCHK(&so->so_rcv, "soreceive 1");
670 nextrecord = m->m_nextpkt;
671 if (pr->pr_flags & PR_ADDR) {
672 #ifdef DIAGNOSTIC
673 if (m->m_type != MT_SONAME)
674 panic("receive 1a");
675 #endif
676 sbfree(&so->so_rcv, m);
677 MFREE(m, so->so_rcv.sb_mb);
678 m = so->so_rcv.sb_mb;
679 }
680 while (m != NULL && m->m_type == MT_CONTROL && error == 0) {
681 sbfree(&so->so_rcv, m);
682 /*
683 * Dispose of any SCM_RIGHTS message that went
684 * through the read path rather than recv.
685 */
686 if (pr->pr_domain->dom_dispose &&
687 mtod(m, struct cmsghdr *)->cmsg_type == SCM_RIGHTS)
688 (*pr->pr_domain->dom_dispose)(m);
689 MFREE(m, so->so_rcv.sb_mb);
690 m = so->so_rcv.sb_mb;
691 }
692
693 /*
694 * If m is non-NULL, we have some data to read. From now on,
695 * make sure to keep sb_lastrecord consistent when working on
696 * the last packet on the chain (nextrecord == NULL) and we
697 * change m->m_nextpkt.
698 */
699 if (m != NULL) {
700 m->m_nextpkt = nextrecord;
701 /*
702 * If nextrecord == NULL (this is a single chain),
703 * then sb_lastrecord may not be valid here if m
704 * was changed earlier.
705 */
706 if (nextrecord == NULL) {
707 KASSERT(so->so_rcv.sb_mb == m);
708 so->so_rcv.sb_lastrecord = m;
709 }
710 type = m->m_type;
711 if (type == MT_OOBDATA)
712 flags |= MSG_OOB;
713 } else {
714 KASSERT(so->so_rcv.sb_mb == m);
715 so->so_rcv.sb_mb = nextrecord;
716 SB_EMPTY_FIXUP(&so->so_rcv);
717 }
718 SBLASTRECORDCHK(&so->so_rcv, "soreceive 2");
719 SBLASTMBUFCHK(&so->so_rcv, "soreceive 2");
720
721 while (m != NULL) {
722 if (m->m_type == MT_OOBDATA) {
723 if (type != MT_OOBDATA)
724 break;
725 } else if (type == MT_OOBDATA)
726 break;
727 #ifdef DIAGNOSTIC
728 else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
729 panic("receive 3");
730 #endif
731 so->so_state &= ~SS_RCVATMARK;
732 if (so->so_oobmark != 0 && so->so_oobmark < m->m_len)
733 break;
734 len = m->m_len;
735 /*
736 * mp is set, just pass back the mbufs.
737 * Sockbuf must be consistent here (points to current mbuf,
738 * it points to next record) when we drop priority;
739 * we must note any additions to the sockbuf when we
740 * block interrupts again.
741 */
742 if (m->m_flags & M_EOR)
743 flags |= MSG_EOR;
744 nextrecord = m->m_nextpkt;
745 sbfree(&so->so_rcv, m);
746 *mp = m;
747 mp = &m->m_next;
748 so->so_rcv.sb_mb = m = m->m_next;
749 *mp = NULL;
750 /*
751 * If m != NULL, we also know that
752 * so->so_rcv.sb_mb != NULL.
753 */
754 KASSERT(so->so_rcv.sb_mb == m);
755 if (m) {
756 m->m_nextpkt = nextrecord;
757 if (nextrecord == NULL)
758 so->so_rcv.sb_lastrecord = m;
759 } else {
760 so->so_rcv.sb_mb = nextrecord;
761 SB_EMPTY_FIXUP(&so->so_rcv);
762 }
763 SBLASTRECORDCHK(&so->so_rcv, "soreceive 3");
764 SBLASTMBUFCHK(&so->so_rcv, "soreceive 3");
765 if (so->so_oobmark) {
766 so->so_oobmark -= len;
767 if (so->so_oobmark == 0) {
768 so->so_state |= SS_RCVATMARK;
769 break;
770 }
771 }
772 if (flags & MSG_EOR)
773 break;
774 }
775
776 if (m != NULL) {
777 m_freem(*mp);
778 *mp = NULL;
779 error = ENOMEM;
780 (void) sbdroprecord(&so->so_rcv);
781 } else {
782 /*
783 * First part is an inline SB_EMPTY_FIXUP(). Second
784 * part makes sure sb_lastrecord is up-to-date if
785 * there is still data in the socket buffer.
786 */
787 so->so_rcv.sb_mb = nextrecord;
788 if (so->so_rcv.sb_mb == NULL) {
789 so->so_rcv.sb_mbtail = NULL;
790 so->so_rcv.sb_lastrecord = NULL;
791 } else if (nextrecord->m_nextpkt == NULL)
792 so->so_rcv.sb_lastrecord = nextrecord;
793 }
794 SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");
795 SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");
796 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
797 (*pr->pr_usrreq)(so, PRU_RCVD, NULL,
798 (struct mbuf *)(long)flags, NULL, curlwp);
799 if (*mp0 == NULL && (flags & MSG_EOR) == 0 &&
800 (so->so_state & SS_CANTRCVMORE) == 0) {
801 sbunlock(&so->so_rcv);
802 goto restart;
803 }
804
805 release:
806 sbunlock(&so->so_rcv);
807 return error;
808 }
809
810 static struct socket *
811 gre_reconf(struct gre_softc *sc, const struct gre_soparm *newsoparm)
812 {
813 struct ifnet *ifp = &sc->sc_if;
814
815 GRE_DPRINTF(sc, "enter\n");
816
817 shutdown:
818 if (sc->sc_soparm.sp_so != NULL) {
819 GRE_DPRINTF(sc, "\n");
820 gre_upcall_remove(sc->sc_soparm.sp_so);
821 softint_disestablish(sc->sc_si);
822 sc->sc_si = NULL;
823 gre_fp_send(sc, GRE_M_DELFP, NULL);
824 gre_clearconf(&sc->sc_soparm, false);
825 }
826
827 if (newsoparm != NULL) {
828 GRE_DPRINTF(sc, "\n");
829 sc->sc_soparm = *newsoparm;
830 newsoparm = NULL;
831 }
832
833 if (sc->sc_soparm.sp_so != NULL) {
834 GRE_DPRINTF(sc, "\n");
835 sc->sc_si = softint_establish(SOFTINT_NET, greintr, sc);
836 gre_upcall_add(sc->sc_soparm.sp_so, sc);
837 if ((ifp->if_flags & IFF_UP) == 0) {
838 GRE_DPRINTF(sc, "down\n");
839 goto shutdown;
840 }
841 }
842
843 GRE_DPRINTF(sc, "\n");
844 if (sc->sc_soparm.sp_so != NULL)
845 sc->sc_if.if_flags |= IFF_RUNNING;
846 else {
847 gre_bufq_purge(&sc->sc_snd);
848 sc->sc_if.if_flags &= ~IFF_RUNNING;
849 }
850 return sc->sc_soparm.sp_so;
851 }
852
853 static int
854 gre_input(struct gre_softc *sc, struct mbuf *m, int hlen,
855 const struct gre_h *gh)
856 {
857 uint16_t flags;
858 uint32_t af; /* af passed to BPF tap */
859 int isr, s;
860 struct ifqueue *ifq;
861
862 sc->sc_if.if_ipackets++;
863 sc->sc_if.if_ibytes += m->m_pkthdr.len;
864
865 hlen += sizeof(struct gre_h);
866
867 /* process GRE flags as packet can be of variable len */
868 flags = ntohs(gh->flags);
869
870 /* Checksum & Offset are present */
871 if ((flags & GRE_CP) | (flags & GRE_RP))
872 hlen += 4;
873 /* We don't support routing fields (variable length) */
874 if (flags & GRE_RP) {
875 sc->sc_if.if_ierrors++;
876 return 0;
877 }
878 if (flags & GRE_KP)
879 hlen += 4;
880 if (flags & GRE_SP)
881 hlen += 4;
882
883 switch (ntohs(gh->ptype)) { /* ethertypes */
884 case ETHERTYPE_IP:
885 ifq = &ipintrq;
886 isr = NETISR_IP;
887 af = AF_INET;
888 break;
889 #ifdef NETATALK
890 case ETHERTYPE_ATALK:
891 ifq = &atintrq1;
892 isr = NETISR_ATALK;
893 af = AF_APPLETALK;
894 break;
895 #endif
896 #ifdef INET6
897 case ETHERTYPE_IPV6:
898 ifq = &ip6intrq;
899 isr = NETISR_IPV6;
900 af = AF_INET6;
901 break;
902 #endif
903 default: /* others not yet supported */
904 GRE_DPRINTF(sc, "unhandled ethertype 0x%04x\n",
905 ntohs(gh->ptype));
906 sc->sc_if.if_noproto++;
907 return 0;
908 }
909
910 if (hlen > m->m_pkthdr.len) {
911 m_freem(m);
912 sc->sc_if.if_ierrors++;
913 return EINVAL;
914 }
915 m_adj(m, hlen);
916
917 #if NBPFILTER > 0
918 if (sc->sc_if.if_bpf != NULL)
919 bpf_mtap_af(sc->sc_if.if_bpf, af, m);
920 #endif /*NBPFILTER > 0*/
921
922 m->m_pkthdr.rcvif = &sc->sc_if;
923
924 s = splnet();
925 if (IF_QFULL(ifq)) {
926 IF_DROP(ifq);
927 m_freem(m);
928 } else {
929 IF_ENQUEUE(ifq, m);
930 }
931 /* we need schednetisr since the address family may change */
932 schednetisr(isr);
933 splx(s);
934
935 return 1; /* packet is done, no further processing needed */
936 }
937
938 /*
939 * The output routine. Takes a packet and encapsulates it in the protocol
940 * given by sc->sc_soparm.sp_proto. See also RFC 1701 and RFC 2004
941 */
942 static int
943 gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
944 struct rtentry *rt)
945 {
946 int error = 0;
947 struct gre_softc *sc = ifp->if_softc;
948 struct gre_h *gh;
949 struct ip *ip;
950 uint8_t ip_tos = 0;
951 uint16_t etype = 0;
952
953 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
954 m_freem(m);
955 error = ENETDOWN;
956 goto end;
957 }
958
959 #if NBPFILTER > 0
960 if (ifp->if_bpf != NULL)
961 bpf_mtap_af(ifp->if_bpf, dst->sa_family, m);
962 #endif
963
964 m->m_flags &= ~(M_BCAST|M_MCAST);
965
966 GRE_DPRINTF(sc, "dst->sa_family=%d\n", dst->sa_family);
967 switch (dst->sa_family) {
968 case AF_INET:
969 ip = mtod(m, struct ip *);
970 ip_tos = ip->ip_tos;
971 etype = htons(ETHERTYPE_IP);
972 break;
973 #ifdef NETATALK
974 case AF_APPLETALK:
975 etype = htons(ETHERTYPE_ATALK);
976 break;
977 #endif
978 #ifdef INET6
979 case AF_INET6:
980 etype = htons(ETHERTYPE_IPV6);
981 break;
982 #endif
983 default:
984 IF_DROP(&ifp->if_snd);
985 m_freem(m);
986 error = EAFNOSUPPORT;
987 goto end;
988 }
989
990 M_PREPEND(m, sizeof(*gh), M_DONTWAIT);
991
992 if (m == NULL) {
993 IF_DROP(&ifp->if_snd);
994 error = ENOBUFS;
995 goto end;
996 }
997
998 gh = mtod(m, struct gre_h *);
999 gh->flags = 0;
1000 gh->ptype = etype;
1001 /* XXX Need to handle IP ToS. Look at how I handle IP TTL. */
1002
1003 ifp->if_opackets++;
1004 ifp->if_obytes += m->m_pkthdr.len;
1005
1006 /* send it off */
1007 if ((error = gre_bufq_enqueue(&sc->sc_snd, m)) != 0) {
1008 sc->sc_oflow_ev.ev_count++;
1009 m_freem(m);
1010 } else
1011 softint_schedule(sc->sc_si);
1012 end:
1013 if (error)
1014 ifp->if_oerrors++;
1015 return error;
1016 }
1017
1018 static int
1019 gre_getname(struct socket *so, int req, struct mbuf *nam, struct lwp *l)
1020 {
1021 return (*so->so_proto->pr_usrreq)(so, req, NULL, nam, NULL, l);
1022 }
1023
1024 static int
1025 gre_getsockname(struct socket *so, struct mbuf *nam, struct lwp *l)
1026 {
1027 return gre_getname(so, PRU_SOCKADDR, nam, l);
1028 }
1029
1030 static int
1031 gre_getpeername(struct socket *so, struct mbuf *nam, struct lwp *l)
1032 {
1033 return gre_getname(so, PRU_PEERADDR, nam, l);
1034 }
1035
1036 static int
1037 gre_getnames(struct socket *so, struct lwp *l, struct sockaddr_storage *src,
1038 struct sockaddr_storage *dst)
1039 {
1040 struct mbuf *m;
1041 struct sockaddr_storage *ss;
1042 int rc;
1043
1044 if ((m = getsombuf(so, MT_SONAME)) == NULL)
1045 return ENOBUFS;
1046
1047 ss = mtod(m, struct sockaddr_storage *);
1048
1049 solock(so);
1050 if ((rc = gre_getsockname(so, m, l)) != 0)
1051 goto out;
1052 *src = *ss;
1053
1054 if ((rc = gre_getpeername(so, m, l)) != 0)
1055 goto out;
1056 *dst = *ss;
1057 out:
1058 sounlock(so);
1059 m_freem(m);
1060 return rc;
1061 }
1062
1063 static void
1064 gre_fp_recvloop(void *arg)
1065 {
1066 struct gre_softc *sc = arg;
1067
1068 mutex_enter(&sc->sc_mtx);
1069 while (gre_fp_recv(sc))
1070 ;
1071 mutex_exit(&sc->sc_mtx);
1072 kthread_exit(0);
1073 }
1074
1075 static bool
1076 gre_fp_recv(struct gre_softc *sc)
1077 {
1078 int fd, ofd, rc;
1079 file_t *fp;
1080
1081 fp = sc->sc_fp;
1082 ofd = sc->sc_fd;
1083 fd = -1;
1084
1085 switch (sc->sc_msg) {
1086 case GRE_M_STOP:
1087 cv_signal(&sc->sc_fp_condvar);
1088 return false;
1089 case GRE_M_SETFP:
1090 mutex_exit(&sc->sc_mtx);
1091 rc = fd_dup(fp, 0, &fd, 0);
1092 mutex_enter(&sc->sc_mtx);
1093 if (rc != 0) {
1094 sc->sc_msg = GRE_M_ERR;
1095 break;
1096 }
1097 /*FALLTHROUGH*/
1098 case GRE_M_DELFP:
1099 mutex_exit(&sc->sc_mtx);
1100 if (ofd != -1 && fd_getfile(ofd) != NULL)
1101 fd_close(ofd);
1102 mutex_enter(&sc->sc_mtx);
1103 sc->sc_fd = fd;
1104 sc->sc_msg = GRE_M_OK;
1105 break;
1106 default:
1107 gre_fp_wait(sc);
1108 return true;
1109 }
1110 cv_signal(&sc->sc_fp_condvar);
1111 return true;
1112 }
1113
1114 static bool
1115 gre_fp_send(struct gre_softc *sc, enum gre_msg msg, file_t *fp)
1116 {
1117 bool rc;
1118
1119 mutex_enter(&sc->sc_mtx);
1120 while (sc->sc_msg != GRE_M_NONE)
1121 gre_fp_wait(sc);
1122 sc->sc_fp = fp;
1123 sc->sc_msg = msg;
1124 cv_signal(&sc->sc_fp_condvar);
1125 while (sc->sc_msg != GRE_M_STOP && sc->sc_msg != GRE_M_OK &&
1126 sc->sc_msg != GRE_M_ERR)
1127 gre_fp_wait(sc);
1128 rc = (sc->sc_msg != GRE_M_ERR);
1129 sc->sc_msg = GRE_M_NONE;
1130 cv_signal(&sc->sc_fp_condvar);
1131 mutex_exit(&sc->sc_mtx);
1132 return rc;
1133 }
1134
1135 static int
1136 gre_ssock(struct ifnet *ifp, struct gre_soparm *sp, int fd)
1137 {
1138 int error = 0;
1139 const struct protosw *pr;
1140 file_t *fp;
1141 struct gre_softc *sc = ifp->if_softc;
1142 struct socket *so;
1143 struct sockaddr_storage dst, src;
1144
1145 if ((fp = fd_getfile(fd)) == NULL)
1146 return EBADF;
1147 if (fp->f_type != DTYPE_SOCKET) {
1148 fd_putfile(fd);
1149 return ENOTSOCK;
1150 }
1151
1152 GRE_DPRINTF(sc, "\n");
1153
1154 so = (struct socket *)fp->f_data;
1155 pr = so->so_proto;
1156
1157 GRE_DPRINTF(sc, "type %d, proto %d\n", pr->pr_type, pr->pr_protocol);
1158
1159 if ((pr->pr_flags & PR_ATOMIC) == 0 ||
1160 (sp->sp_type != 0 && pr->pr_type != sp->sp_type) ||
1161 (sp->sp_proto != 0 && pr->pr_protocol != 0 &&
1162 pr->pr_protocol != sp->sp_proto)) {
1163 error = EINVAL;
1164 goto err;
1165 }
1166
1167 GRE_DPRINTF(sc, "\n");
1168
1169 /* check address */
1170 if ((error = gre_getnames(so, curlwp, &src, &dst)) != 0)
1171 goto err;
1172
1173 GRE_DPRINTF(sc, "\n");
1174
1175 if (!gre_fp_send(sc, GRE_M_SETFP, fp)) {
1176 error = EBUSY;
1177 goto err;
1178 }
1179
1180 GRE_DPRINTF(sc, "\n");
1181
1182 sp->sp_src = src;
1183 sp->sp_dst = dst;
1184
1185 sp->sp_so = so;
1186
1187 err:
1188 fd_putfile(fd);
1189 return error;
1190 }
1191
1192 static bool
1193 sockaddr_is_anyaddr(const struct sockaddr *sa)
1194 {
1195 socklen_t anylen, salen;
1196 const void *anyaddr, *addr;
1197
1198 if ((anyaddr = sockaddr_anyaddr(sa, &anylen)) == NULL ||
1199 (addr = sockaddr_const_addr(sa, &salen)) == NULL)
1200 return false;
1201
1202 if (salen > anylen)
1203 return false;
1204
1205 return memcmp(anyaddr, addr, MIN(anylen, salen)) == 0;
1206 }
1207
1208 static bool
1209 gre_is_nullconf(const struct gre_soparm *sp)
1210 {
1211 return sockaddr_is_anyaddr(sstocsa(&sp->sp_src)) ||
1212 sockaddr_is_anyaddr(sstocsa(&sp->sp_dst));
1213 }
1214
1215 static void
1216 gre_clearconf(struct gre_soparm *sp, bool force)
1217 {
1218 if (sp->sp_bysock || force) {
1219 sockaddr_copy(sstosa(&sp->sp_src), sizeof(sp->sp_src),
1220 sockaddr_any(sstosa(&sp->sp_src)));
1221 sockaddr_copy(sstosa(&sp->sp_dst), sizeof(sp->sp_dst),
1222 sockaddr_any(sstosa(&sp->sp_dst)));
1223 sp->sp_bysock = false;
1224 }
1225 sp->sp_so = NULL; /* XXX */
1226 }
1227
1228 static int
1229 gre_ioctl_lock(struct gre_softc *sc)
1230 {
1231 mutex_enter(&sc->sc_mtx);
1232
1233 while (sc->sc_state == GRE_S_IOCTL)
1234 gre_wait(sc);
1235
1236 if (sc->sc_state != GRE_S_IDLE) {
1237 cv_signal(&sc->sc_condvar);
1238 mutex_exit(&sc->sc_mtx);
1239 GRE_DPRINTF(sc, "\n");
1240 return ENXIO;
1241 }
1242
1243 sc->sc_state = GRE_S_IOCTL;
1244
1245 mutex_exit(&sc->sc_mtx);
1246 return 0;
1247 }
1248
1249 static void
1250 gre_ioctl_unlock(struct gre_softc *sc)
1251 {
1252 mutex_enter(&sc->sc_mtx);
1253
1254 KASSERT(sc->sc_state == GRE_S_IOCTL);
1255 sc->sc_state = GRE_S_IDLE;
1256 cv_signal(&sc->sc_condvar);
1257
1258 mutex_exit(&sc->sc_mtx);
1259 }
1260
1261 static int
1262 gre_ioctl(struct ifnet *ifp, const u_long cmd, void *data)
1263 {
1264 struct ifreq *ifr;
1265 struct if_laddrreq *lifr = (struct if_laddrreq *)data;
1266 struct gre_softc *sc = ifp->if_softc;
1267 struct gre_soparm *sp;
1268 int fd, error = 0, oproto, otype, s;
1269 struct gre_soparm sp0;
1270
1271 ifr = data;
1272
1273 GRE_DPRINTF(sc, "cmd %lu\n", cmd);
1274
1275 switch (cmd) {
1276 case SIOCSIFFLAGS:
1277 case SIOCSIFMTU:
1278 case GRESPROTO:
1279 case GRESADDRD:
1280 case GRESADDRS:
1281 case GRESSOCK:
1282 case GREDSOCK:
1283 case SIOCSLIFPHYADDR:
1284 case SIOCDIFPHYADDR:
1285 if (kauth_authorize_network(curlwp->l_cred,
1286 KAUTH_NETWORK_INTERFACE,
1287 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
1288 NULL) != 0)
1289 return EPERM;
1290 break;
1291 default:
1292 break;
1293 }
1294
1295 if ((error = gre_ioctl_lock(sc)) != 0) {
1296 GRE_DPRINTF(sc, "\n");
1297 return error;
1298 }
1299 s = splnet();
1300
1301 sp0 = sc->sc_soparm;
1302 sp0.sp_so = NULL;
1303 sp = &sp0;
1304
1305 GRE_DPRINTF(sc, "\n");
1306
1307 switch (cmd) {
1308 case SIOCSIFADDR:
1309 GRE_DPRINTF(sc, "\n");
1310 if ((ifp->if_flags & IFF_UP) != 0)
1311 break;
1312 gre_clearconf(sp, false);
1313 ifp->if_flags |= IFF_UP;
1314 goto mksocket;
1315 case SIOCSIFDSTADDR:
1316 break;
1317 case SIOCSIFFLAGS:
1318 oproto = sp->sp_proto;
1319 otype = sp->sp_type;
1320 switch (ifr->ifr_flags & (IFF_LINK0|IFF_LINK2)) {
1321 case IFF_LINK0|IFF_LINK2:
1322 sp->sp_proto = IPPROTO_UDP;
1323 sp->sp_type = SOCK_DGRAM;
1324 break;
1325 case IFF_LINK2:
1326 sp->sp_proto = 0;
1327 sp->sp_type = 0;
1328 break;
1329 case IFF_LINK0:
1330 sp->sp_proto = IPPROTO_GRE;
1331 sp->sp_type = SOCK_RAW;
1332 break;
1333 default:
1334 GRE_DPRINTF(sc, "\n");
1335 error = EINVAL;
1336 goto out;
1337 }
1338 GRE_DPRINTF(sc, "\n");
1339 gre_clearconf(sp, false);
1340 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
1341 (IFF_UP|IFF_RUNNING) &&
1342 (oproto == sp->sp_proto || sp->sp_proto == 0) &&
1343 (otype == sp->sp_type || sp->sp_type == 0))
1344 break;
1345 switch (sp->sp_proto) {
1346 case IPPROTO_UDP:
1347 case IPPROTO_GRE:
1348 goto mksocket;
1349 default:
1350 break;
1351 }
1352 break;
1353 case SIOCSIFMTU:
1354 /* XXX determine MTU automatically by probing w/
1355 * XXX do-not-fragment packets?
1356 */
1357 if (ifr->ifr_mtu < 576) {
1358 error = EINVAL;
1359 break;
1360 }
1361 /*FALLTHROUGH*/
1362 case SIOCGIFMTU:
1363 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
1364 error = 0;
1365 break;
1366 case SIOCADDMULTI:
1367 case SIOCDELMULTI:
1368 if (ifr == NULL) {
1369 error = EAFNOSUPPORT;
1370 break;
1371 }
1372 switch (ifreq_getaddr(cmd, ifr)->sa_family) {
1373 #ifdef INET
1374 case AF_INET:
1375 break;
1376 #endif
1377 #ifdef INET6
1378 case AF_INET6:
1379 break;
1380 #endif
1381 default:
1382 error = EAFNOSUPPORT;
1383 break;
1384 }
1385 break;
1386 case GRESPROTO:
1387 gre_clearconf(sp, false);
1388 oproto = sp->sp_proto;
1389 otype = sp->sp_type;
1390 sp->sp_proto = ifr->ifr_flags;
1391 switch (sp->sp_proto) {
1392 case IPPROTO_UDP:
1393 ifp->if_flags |= IFF_LINK0|IFF_LINK2;
1394 sp->sp_type = SOCK_DGRAM;
1395 break;
1396 case IPPROTO_GRE:
1397 ifp->if_flags |= IFF_LINK0;
1398 ifp->if_flags &= ~IFF_LINK2;
1399 sp->sp_type = SOCK_RAW;
1400 break;
1401 case 0:
1402 ifp->if_flags &= ~IFF_LINK0;
1403 ifp->if_flags |= IFF_LINK2;
1404 sp->sp_type = 0;
1405 break;
1406 default:
1407 error = EPROTONOSUPPORT;
1408 break;
1409 }
1410 if ((oproto == sp->sp_proto || sp->sp_proto == 0) &&
1411 (otype == sp->sp_type || sp->sp_type == 0))
1412 break;
1413 switch (sp->sp_proto) {
1414 case IPPROTO_UDP:
1415 case IPPROTO_GRE:
1416 goto mksocket;
1417 default:
1418 break;
1419 }
1420 break;
1421 case GREGPROTO:
1422 ifr->ifr_flags = sp->sp_proto;
1423 break;
1424 case GRESADDRS:
1425 case GRESADDRD:
1426 gre_clearconf(sp, false);
1427 /* set tunnel endpoints and mark interface as up */
1428 switch (cmd) {
1429 case GRESADDRS:
1430 sockaddr_copy(sstosa(&sp->sp_src),
1431 sizeof(sp->sp_src), ifreq_getaddr(cmd, ifr));
1432 break;
1433 case GRESADDRD:
1434 sockaddr_copy(sstosa(&sp->sp_dst),
1435 sizeof(sp->sp_dst), ifreq_getaddr(cmd, ifr));
1436 break;
1437 }
1438 checkaddr:
1439 if (sockaddr_any(sstosa(&sp->sp_src)) == NULL ||
1440 sockaddr_any(sstosa(&sp->sp_dst)) == NULL) {
1441 error = EINVAL;
1442 break;
1443 }
1444 /* let gre_socreate() check the rest */
1445 mksocket:
1446 GRE_DPRINTF(sc, "\n");
1447 /* If we're administratively down, or the configuration
1448 * is empty, there's no use creating a socket.
1449 */
1450 if ((ifp->if_flags & IFF_UP) == 0 || gre_is_nullconf(sp))
1451 goto sendconf;
1452
1453 GRE_DPRINTF(sc, "\n");
1454 fd = 0;
1455 error = gre_socreate(sc, sp, &fd);
1456 if (error != 0)
1457 break;
1458
1459 setsock:
1460 GRE_DPRINTF(sc, "\n");
1461
1462 error = gre_ssock(ifp, sp, fd);
1463
1464 if (cmd != GRESSOCK) {
1465 GRE_DPRINTF(sc, "\n");
1466 /* XXX v. dodgy */
1467 if (fd_getfile(fd) != NULL)
1468 fd_close(fd);
1469 }
1470
1471 if (error == 0) {
1472 sendconf:
1473 GRE_DPRINTF(sc, "\n");
1474 ifp->if_flags &= ~IFF_RUNNING;
1475 gre_reconf(sc, sp);
1476 }
1477
1478 break;
1479 case GREGADDRS:
1480 ifreq_setaddr(cmd, ifr, sstosa(&sp->sp_src));
1481 break;
1482 case GREGADDRD:
1483 ifreq_setaddr(cmd, ifr, sstosa(&sp->sp_dst));
1484 break;
1485 case GREDSOCK:
1486 GRE_DPRINTF(sc, "\n");
1487 if (sp->sp_bysock)
1488 ifp->if_flags &= ~IFF_UP;
1489 gre_clearconf(sp, false);
1490 goto mksocket;
1491 case GRESSOCK:
1492 GRE_DPRINTF(sc, "\n");
1493 gre_clearconf(sp, true);
1494 fd = (int)ifr->ifr_value;
1495 sp->sp_bysock = true;
1496 ifp->if_flags |= IFF_UP;
1497 goto setsock;
1498 case SIOCSLIFPHYADDR:
1499 GRE_DPRINTF(sc, "\n");
1500 if (lifr->addr.ss_family != lifr->dstaddr.ss_family) {
1501 error = EAFNOSUPPORT;
1502 break;
1503 }
1504 sockaddr_copy(sstosa(&sp->sp_src), sizeof(sp->sp_src),
1505 sstosa(&lifr->addr));
1506 sockaddr_copy(sstosa(&sp->sp_dst), sizeof(sp->sp_dst),
1507 sstosa(&lifr->dstaddr));
1508 GRE_DPRINTF(sc, "\n");
1509 goto checkaddr;
1510 case SIOCDIFPHYADDR:
1511 GRE_DPRINTF(sc, "\n");
1512 gre_clearconf(sp, true);
1513 ifp->if_flags &= ~IFF_UP;
1514 goto mksocket;
1515 case SIOCGLIFPHYADDR:
1516 GRE_DPRINTF(sc, "\n");
1517 if (gre_is_nullconf(sp)) {
1518 error = EADDRNOTAVAIL;
1519 break;
1520 }
1521 sockaddr_copy(sstosa(&lifr->addr), sizeof(lifr->addr),
1522 sstosa(&sp->sp_src));
1523 sockaddr_copy(sstosa(&lifr->dstaddr), sizeof(lifr->dstaddr),
1524 sstosa(&sp->sp_dst));
1525 GRE_DPRINTF(sc, "\n");
1526 break;
1527 default:
1528 error = EINVAL;
1529 break;
1530 }
1531 out:
1532 GRE_DPRINTF(sc, "\n");
1533 splx(s);
1534 gre_ioctl_unlock(sc);
1535 return error;
1536 }
1537
1538 #endif
1539
1540 void greattach(int);
1541
1542 /* ARGSUSED */
1543 void
1544 greattach(int count)
1545 {
1546 #ifdef INET
1547 if_clone_attach(&gre_cloner);
1548 #endif
1549 }
Cache object: f070dc6c67aad05a4244a033152a13e3
|