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