Print this page
OS-4865 lxbrand async socket errors catch programs off guard
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4213 lxbrand should be able to set TCP_DEFER_ACCEPT after other socket operations
OS-3893 sendfile compat checks shouldn't be done in so_sendmblk
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>


 111         return (EOPNOTSUPP);
 112 }
 113 
 114 /*
 115  * Generic Socket Ops
 116  */
 117 
 118 /* ARGSUSED */
 119 int
 120 so_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
 121 {
 122         return (socket_init_common(so, pso, flags, cr));
 123 }
 124 
 125 int
 126 so_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
 127     int flags, struct cred *cr)
 128 {
 129         int error;
 130 
 131         SO_BLOCK_FALLBACK(so, SOP_BIND(so, name, namelen, flags, cr));
 132 
 133         ASSERT(flags == _SOBIND_XPG4_2 || flags == _SOBIND_SOCKBSD);
 134 
 135         /* X/Open requires this check */
 136         if ((so->so_state & SS_CANTSENDMORE) && !xnet_skip_checks) {
 137                 if (xnet_check_print) {
 138                         printf("sockfs: X/Open bind state check "
 139                             "caused EINVAL\n");
 140                 }
 141                 error = EINVAL;
 142                 goto done;
 143         }
 144 
 145         /*
 146          * a bind to a NULL address is interpreted as unbind. So just
 147          * do the downcall.
 148          */
 149         if (name == NULL)
 150                 goto dobind;
 151 


 288 
 289         return (error);
 290 }
 291 
 292 
 293 int
 294 so_connect(struct sonode *so, struct sockaddr *name,
 295     socklen_t namelen, int fflag, int flags, struct cred *cr)
 296 {
 297         int error = 0;
 298         sock_connid_t id;
 299 
 300         ASSERT(MUTEX_NOT_HELD(&so->so_lock));
 301         SO_BLOCK_FALLBACK(so, SOP_CONNECT(so, name, namelen, fflag, flags, cr));
 302 
 303         /*
 304          * If there is a pending error, return error
 305          * This can happen if a non blocking operation caused an error.
 306          */
 307 
 308         if (so->so_error != 0) {
 309                 mutex_enter(&so->so_lock);
 310                 error = sogeterr(so, B_TRUE);
 311                 mutex_exit(&so->so_lock);
 312                 if (error != 0)
 313                         goto done;
 314         }
 315 
 316         if (so->so_filter_active == 0 ||
 317             (error = sof_filter_connect(so, (struct sockaddr *)name,
 318             &namelen, cr)) < 0) {
 319                 error = (*so->so_downcalls->sd_connect)(so->so_proto_handle,
 320                     name, namelen, &id, cr);
 321 
 322                 if (error == EINPROGRESS)
 323                         error = so_wait_connected(so,
 324                             fflag & (FNONBLOCK|FNDELAY), id);
 325         }
 326 done:
 327         SO_UNBLOCK_FALLBACK(so);
 328         return (error);


 387                 SO_UNBLOCK_FALLBACK(so);
 388                 return (EOPNOTSUPP);
 389         }
 390 
 391         if ((so->so_mode & SM_ATOMIC) &&
 392             uiop->uio_resid > so->so_proto_props.sopp_maxpsz &&
 393             so->so_proto_props.sopp_maxpsz != -1) {
 394                 SO_UNBLOCK_FALLBACK(so);
 395                 return (EMSGSIZE);
 396         }
 397 
 398         /*
 399          * For atomic sends we will only do one iteration.
 400          */
 401         do {
 402                 if (so->so_state & SS_CANTSENDMORE) {
 403                         error = EPIPE;
 404                         break;
 405                 }
 406 
 407                 if (so->so_error != 0) {
 408                         mutex_enter(&so->so_lock);
 409                         error = sogeterr(so, B_TRUE);
 410                         mutex_exit(&so->so_lock);
 411                         if (error != 0)
 412                                 break;
 413                 }
 414 
 415                 /*
 416                  * Send down OOB messages even if the send path is being
 417                  * flow controlled (assuming the protocol supports OOB data).
 418                  */
 419                 if (flags & MSG_OOB) {
 420                         if ((so->so_mode & SM_EXDATA) == 0) {
 421                                 error = EOPNOTSUPP;
 422                                 break;
 423                         }
 424                 } else if (SO_SND_FLOWCTRLD(so)) {
 425                         /*
 426                          * Need to wait until the protocol is ready to receive
 427                          * more data for transmission.


 496         error = 0;
 497         dontblock = (msg->msg_flags & MSG_DONTWAIT) ||
 498             (fflag & (FNONBLOCK|FNDELAY));
 499         size = msgdsize(mp);
 500 
 501         if ((so->so_mode & SM_ATOMIC) &&
 502             size > so->so_proto_props.sopp_maxpsz &&
 503             so->so_proto_props.sopp_maxpsz != -1) {
 504                 SO_UNBLOCK_FALLBACK(so);
 505                 return (EMSGSIZE);
 506         }
 507 
 508         while (mp != NULL) {
 509                 mblk_t *nmp, *last_mblk;
 510                 size_t mlen;
 511 
 512                 if (so->so_state & SS_CANTSENDMORE) {
 513                         error = EPIPE;
 514                         break;
 515                 }
 516                 if (so->so_error != 0) {
 517                         mutex_enter(&so->so_lock);
 518                         error = sogeterr(so, B_TRUE);
 519                         mutex_exit(&so->so_lock);
 520                         if (error != 0)
 521                                 break;
 522                 }
 523                 /* Socket filters are not flow controlled */
 524                 if (SO_SND_FLOWCTRLD(so) && !fil_inject) {
 525                         /*
 526                          * Need to wait until the protocol is ready to receive
 527                          * more data for transmission.
 528                          */
 529                         if ((error = so_snd_wait_qnotfull(so, dontblock)) != 0)
 530                                 break;
 531                 }
 532 
 533                 /*
 534                  * We only allow so_maxpsz of data to be sent down to
 535                  * the protocol at time.
 536                  */


 569 
 570                 *mpp = mp = nmp;
 571         }
 572         /* Let the filter know whether the protocol is flow controlled */
 573         if (fil_inject && error == 0 && SO_SND_FLOWCTRLD(so))
 574                 error = ENOSPC;
 575 
 576         return (error);
 577 }
 578 
 579 #pragma inline(so_sendmblk_impl)
 580 
 581 int
 582 so_sendmblk(struct sonode *so, struct nmsghdr *msg, int fflag,
 583     struct cred *cr, mblk_t **mpp)
 584 {
 585         int error;
 586 
 587         SO_BLOCK_FALLBACK(so, SOP_SENDMBLK(so, msg, fflag, cr, mpp));
 588 
 589         if ((so->so_mode & SM_SENDFILESUPP) == 0) {
 590                 SO_UNBLOCK_FALLBACK(so);
 591                 return (EOPNOTSUPP);
 592         }
 593 
 594         error = so_sendmblk_impl(so, msg, fflag, cr, mpp, so->so_filter_top,
 595             B_FALSE);
 596 
 597         SO_UNBLOCK_FALLBACK(so);
 598 
 599         return (error);
 600 }
 601 
 602 int
 603 so_shutdown(struct sonode *so, int how, struct cred *cr)
 604 {
 605         int error;
 606 
 607         SO_BLOCK_FALLBACK(so, SOP_SHUTDOWN(so, how, cr));
 608 
 609         /*
 610          * SunOS 4.X has no check for datagram sockets.
 611          * 5.X checks that it is connected (ENOTCONN)
 612          * X/Open requires that we check the connected state.
 613          */


 636                 /* wait for active reader to finish */
 637                 (void) so_lock_read(so, 0);
 638 
 639                 so_rcv_flush(so);
 640 
 641                 so_unlock_read(so);
 642                 mutex_exit(&so->so_lock);
 643         }
 644 
 645 done:
 646         SO_UNBLOCK_FALLBACK(so);
 647         return (error);
 648 }
 649 
 650 int
 651 so_getsockname(struct sonode *so, struct sockaddr *addr,
 652     socklen_t *addrlen, struct cred *cr)
 653 {
 654         int error;
 655 
 656         SO_BLOCK_FALLBACK(so, SOP_GETSOCKNAME(so, addr, addrlen, cr));
 657 
 658         if (so->so_filter_active == 0 ||
 659             (error = sof_filter_getsockname(so, addr, addrlen, cr)) < 0)
 660                 error = (*so->so_downcalls->sd_getsockname)
 661                     (so->so_proto_handle, addr, addrlen, cr);
 662 
 663         SO_UNBLOCK_FALLBACK(so);
 664         return (error);
 665 }
 666 
 667 int
 668 so_getpeername(struct sonode *so, struct sockaddr *addr,
 669     socklen_t *addrlen, boolean_t accept, struct cred *cr)
 670 {
 671         int error;
 672 
 673         SO_BLOCK_FALLBACK(so, SOP_GETPEERNAME(so, addr, addrlen, accept, cr));
 674 
 675         if (accept) {
 676                 error = (*so->so_downcalls->sd_getpeername)


 685                 }
 686         } else if (so->so_filter_active == 0 ||
 687             (error = sof_filter_getpeername(so, addr, addrlen, cr)) < 0) {
 688                 error = (*so->so_downcalls->sd_getpeername)
 689                     (so->so_proto_handle, addr, addrlen, cr);
 690         }
 691 
 692         SO_UNBLOCK_FALLBACK(so);
 693         return (error);
 694 }
 695 
 696 int
 697 so_getsockopt(struct sonode *so, int level, int option_name,
 698     void *optval, socklen_t *optlenp, int flags, struct cred *cr)
 699 {
 700         int error = 0;
 701 
 702         if (level == SOL_FILTER)
 703                 return (sof_getsockopt(so, option_name, optval, optlenp, cr));
 704 
 705         SO_BLOCK_FALLBACK(so,
 706             SOP_GETSOCKOPT(so, level, option_name, optval, optlenp, flags, cr));
 707 
 708         if ((so->so_filter_active == 0 ||
 709             (error = sof_filter_getsockopt(so, level, option_name, optval,
 710             optlenp, cr)) < 0) &&
 711             (error = socket_getopt_common(so, level, option_name, optval,
 712             optlenp, flags)) < 0) {
 713                 error = (*so->so_downcalls->sd_getsockopt)
 714                     (so->so_proto_handle, level, option_name, optval, optlenp,
 715                     cr);
 716                 if (error ==  ENOPROTOOPT) {
 717                         if (level == SOL_SOCKET) {
 718                                 /*
 719                                  * If a protocol does not support a particular
 720                                  * socket option, set can fail (not allowed)
 721                                  * but get can not fail. This is the previous
 722                                  * sockfs bahvior.
 723                                  */
 724                                 switch (option_name) {
 725                                 case SO_LINGER:


 774                                 }
 775                         }
 776                 }
 777         }
 778 
 779         SO_UNBLOCK_FALLBACK(so);
 780         return (error);
 781 }
 782 
 783 int
 784 so_setsockopt(struct sonode *so, int level, int option_name,
 785     const void *optval, socklen_t optlen, struct cred *cr)
 786 {
 787         int error = 0;
 788         struct timeval tl;
 789         const void *opt = optval;
 790 
 791         if (level == SOL_FILTER)
 792                 return (sof_setsockopt(so, option_name, optval, optlen, cr));
 793 
 794         SO_BLOCK_FALLBACK(so,
 795             SOP_SETSOCKOPT(so, level, option_name, optval, optlen, cr));
 796 
 797         /* X/Open requires this check */
 798         if (so->so_state & SS_CANTSENDMORE && !xnet_skip_checks) {
 799                 SO_UNBLOCK_FALLBACK(so);
 800                 if (xnet_check_print)
 801                         printf("sockfs: X/Open setsockopt check => EINVAL\n");
 802                 return (EINVAL);
 803         }
 804 
 805         if (so->so_filter_active > 0 &&
 806             (error = sof_filter_setsockopt(so, level, option_name,
 807             (void *)optval, &optlen, cr)) >= 0)
 808                 goto done;
 809 
 810         if (level == SOL_SOCKET) {
 811                 switch (option_name) {
 812                 case SO_RCVTIMEO:
 813                 case SO_SNDTIMEO: {
 814                         /*


 859         }
 860         error = (*so->so_downcalls->sd_setsockopt)
 861             (so->so_proto_handle, level, option_name, opt, optlen, cr);
 862 done:
 863         SO_UNBLOCK_FALLBACK(so);
 864         return (error);
 865 }
 866 
 867 int
 868 so_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode,
 869     struct cred *cr, int32_t *rvalp)
 870 {
 871         int error = 0;
 872 
 873         SO_BLOCK_FALLBACK(so, SOP_IOCTL(so, cmd, arg, mode, cr, rvalp));
 874 
 875         /*
 876          * If there is a pending error, return error
 877          * This can happen if a non blocking operation caused an error.
 878          */
 879         if (so->so_error != 0) {
 880                 mutex_enter(&so->so_lock);
 881                 error = sogeterr(so, B_TRUE);
 882                 mutex_exit(&so->so_lock);
 883                 if (error != 0)
 884                         goto done;
 885         }
 886 
 887         /*
 888          * calling strioc can result in the socket falling back to TPI,
 889          * if that is supported.
 890          */
 891         if ((so->so_filter_active == 0 ||
 892             (error = sof_filter_ioctl(so, cmd, arg, mode,
 893             rvalp, cr)) < 0) &&
 894             (error = socket_ioctl_common(so, cmd, arg, mode, cr, rvalp)) < 0 &&
 895             (error = socket_strioc_common(so, cmd, arg, mode, cr, rvalp)) < 0) {
 896                 error = (*so->so_downcalls->sd_ioctl)(so->so_proto_handle,
 897                     cmd, arg, mode, rvalp, cr);
 898         }
 899 




 111         return (EOPNOTSUPP);
 112 }
 113 
 114 /*
 115  * Generic Socket Ops
 116  */
 117 
 118 /* ARGSUSED */
 119 int
 120 so_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
 121 {
 122         return (socket_init_common(so, pso, flags, cr));
 123 }
 124 
 125 int
 126 so_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
 127     int flags, struct cred *cr)
 128 {
 129         int error;
 130 
 131         SO_BLOCK_FALLBACK_SAFE(so, SOP_BIND(so, name, namelen, flags, cr));
 132 
 133         ASSERT(flags == _SOBIND_XPG4_2 || flags == _SOBIND_SOCKBSD);
 134 
 135         /* X/Open requires this check */
 136         if ((so->so_state & SS_CANTSENDMORE) && !xnet_skip_checks) {
 137                 if (xnet_check_print) {
 138                         printf("sockfs: X/Open bind state check "
 139                             "caused EINVAL\n");
 140                 }
 141                 error = EINVAL;
 142                 goto done;
 143         }
 144 
 145         /*
 146          * a bind to a NULL address is interpreted as unbind. So just
 147          * do the downcall.
 148          */
 149         if (name == NULL)
 150                 goto dobind;
 151 


 288 
 289         return (error);
 290 }
 291 
 292 
 293 int
 294 so_connect(struct sonode *so, struct sockaddr *name,
 295     socklen_t namelen, int fflag, int flags, struct cred *cr)
 296 {
 297         int error = 0;
 298         sock_connid_t id;
 299 
 300         ASSERT(MUTEX_NOT_HELD(&so->so_lock));
 301         SO_BLOCK_FALLBACK(so, SOP_CONNECT(so, name, namelen, fflag, flags, cr));
 302 
 303         /*
 304          * If there is a pending error, return error
 305          * This can happen if a non blocking operation caused an error.
 306          */
 307 
 308         if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
 309                 mutex_enter(&so->so_lock);
 310                 error = sogeterr(so, B_TRUE);
 311                 mutex_exit(&so->so_lock);
 312                 if (error != 0)
 313                         goto done;
 314         }
 315 
 316         if (so->so_filter_active == 0 ||
 317             (error = sof_filter_connect(so, (struct sockaddr *)name,
 318             &namelen, cr)) < 0) {
 319                 error = (*so->so_downcalls->sd_connect)(so->so_proto_handle,
 320                     name, namelen, &id, cr);
 321 
 322                 if (error == EINPROGRESS)
 323                         error = so_wait_connected(so,
 324                             fflag & (FNONBLOCK|FNDELAY), id);
 325         }
 326 done:
 327         SO_UNBLOCK_FALLBACK(so);
 328         return (error);


 387                 SO_UNBLOCK_FALLBACK(so);
 388                 return (EOPNOTSUPP);
 389         }
 390 
 391         if ((so->so_mode & SM_ATOMIC) &&
 392             uiop->uio_resid > so->so_proto_props.sopp_maxpsz &&
 393             so->so_proto_props.sopp_maxpsz != -1) {
 394                 SO_UNBLOCK_FALLBACK(so);
 395                 return (EMSGSIZE);
 396         }
 397 
 398         /*
 399          * For atomic sends we will only do one iteration.
 400          */
 401         do {
 402                 if (so->so_state & SS_CANTSENDMORE) {
 403                         error = EPIPE;
 404                         break;
 405                 }
 406 
 407                 if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
 408                         mutex_enter(&so->so_lock);
 409                         error = sogeterr(so, B_TRUE);
 410                         mutex_exit(&so->so_lock);
 411                         if (error != 0)
 412                                 break;
 413                 }
 414 
 415                 /*
 416                  * Send down OOB messages even if the send path is being
 417                  * flow controlled (assuming the protocol supports OOB data).
 418                  */
 419                 if (flags & MSG_OOB) {
 420                         if ((so->so_mode & SM_EXDATA) == 0) {
 421                                 error = EOPNOTSUPP;
 422                                 break;
 423                         }
 424                 } else if (SO_SND_FLOWCTRLD(so)) {
 425                         /*
 426                          * Need to wait until the protocol is ready to receive
 427                          * more data for transmission.


 496         error = 0;
 497         dontblock = (msg->msg_flags & MSG_DONTWAIT) ||
 498             (fflag & (FNONBLOCK|FNDELAY));
 499         size = msgdsize(mp);
 500 
 501         if ((so->so_mode & SM_ATOMIC) &&
 502             size > so->so_proto_props.sopp_maxpsz &&
 503             so->so_proto_props.sopp_maxpsz != -1) {
 504                 SO_UNBLOCK_FALLBACK(so);
 505                 return (EMSGSIZE);
 506         }
 507 
 508         while (mp != NULL) {
 509                 mblk_t *nmp, *last_mblk;
 510                 size_t mlen;
 511 
 512                 if (so->so_state & SS_CANTSENDMORE) {
 513                         error = EPIPE;
 514                         break;
 515                 }
 516                 if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
 517                         mutex_enter(&so->so_lock);
 518                         error = sogeterr(so, B_TRUE);
 519                         mutex_exit(&so->so_lock);
 520                         if (error != 0)
 521                                 break;
 522                 }
 523                 /* Socket filters are not flow controlled */
 524                 if (SO_SND_FLOWCTRLD(so) && !fil_inject) {
 525                         /*
 526                          * Need to wait until the protocol is ready to receive
 527                          * more data for transmission.
 528                          */
 529                         if ((error = so_snd_wait_qnotfull(so, dontblock)) != 0)
 530                                 break;
 531                 }
 532 
 533                 /*
 534                  * We only allow so_maxpsz of data to be sent down to
 535                  * the protocol at time.
 536                  */


 569 
 570                 *mpp = mp = nmp;
 571         }
 572         /* Let the filter know whether the protocol is flow controlled */
 573         if (fil_inject && error == 0 && SO_SND_FLOWCTRLD(so))
 574                 error = ENOSPC;
 575 
 576         return (error);
 577 }
 578 
 579 #pragma inline(so_sendmblk_impl)
 580 
 581 int
 582 so_sendmblk(struct sonode *so, struct nmsghdr *msg, int fflag,
 583     struct cred *cr, mblk_t **mpp)
 584 {
 585         int error;
 586 
 587         SO_BLOCK_FALLBACK(so, SOP_SENDMBLK(so, msg, fflag, cr, mpp));
 588 





 589         error = so_sendmblk_impl(so, msg, fflag, cr, mpp, so->so_filter_top,
 590             B_FALSE);
 591 
 592         SO_UNBLOCK_FALLBACK(so);
 593 
 594         return (error);
 595 }
 596 
 597 int
 598 so_shutdown(struct sonode *so, int how, struct cred *cr)
 599 {
 600         int error;
 601 
 602         SO_BLOCK_FALLBACK(so, SOP_SHUTDOWN(so, how, cr));
 603 
 604         /*
 605          * SunOS 4.X has no check for datagram sockets.
 606          * 5.X checks that it is connected (ENOTCONN)
 607          * X/Open requires that we check the connected state.
 608          */


 631                 /* wait for active reader to finish */
 632                 (void) so_lock_read(so, 0);
 633 
 634                 so_rcv_flush(so);
 635 
 636                 so_unlock_read(so);
 637                 mutex_exit(&so->so_lock);
 638         }
 639 
 640 done:
 641         SO_UNBLOCK_FALLBACK(so);
 642         return (error);
 643 }
 644 
 645 int
 646 so_getsockname(struct sonode *so, struct sockaddr *addr,
 647     socklen_t *addrlen, struct cred *cr)
 648 {
 649         int error;
 650 
 651         SO_BLOCK_FALLBACK_SAFE(so, SOP_GETSOCKNAME(so, addr, addrlen, cr));
 652 
 653         if (so->so_filter_active == 0 ||
 654             (error = sof_filter_getsockname(so, addr, addrlen, cr)) < 0)
 655                 error = (*so->so_downcalls->sd_getsockname)
 656                     (so->so_proto_handle, addr, addrlen, cr);
 657 
 658         SO_UNBLOCK_FALLBACK(so);
 659         return (error);
 660 }
 661 
 662 int
 663 so_getpeername(struct sonode *so, struct sockaddr *addr,
 664     socklen_t *addrlen, boolean_t accept, struct cred *cr)
 665 {
 666         int error;
 667 
 668         SO_BLOCK_FALLBACK(so, SOP_GETPEERNAME(so, addr, addrlen, accept, cr));
 669 
 670         if (accept) {
 671                 error = (*so->so_downcalls->sd_getpeername)


 680                 }
 681         } else if (so->so_filter_active == 0 ||
 682             (error = sof_filter_getpeername(so, addr, addrlen, cr)) < 0) {
 683                 error = (*so->so_downcalls->sd_getpeername)
 684                     (so->so_proto_handle, addr, addrlen, cr);
 685         }
 686 
 687         SO_UNBLOCK_FALLBACK(so);
 688         return (error);
 689 }
 690 
 691 int
 692 so_getsockopt(struct sonode *so, int level, int option_name,
 693     void *optval, socklen_t *optlenp, int flags, struct cred *cr)
 694 {
 695         int error = 0;
 696 
 697         if (level == SOL_FILTER)
 698                 return (sof_getsockopt(so, option_name, optval, optlenp, cr));
 699 
 700         SO_BLOCK_FALLBACK_SAFE(so,
 701             SOP_GETSOCKOPT(so, level, option_name, optval, optlenp, flags, cr));
 702 
 703         if ((so->so_filter_active == 0 ||
 704             (error = sof_filter_getsockopt(so, level, option_name, optval,
 705             optlenp, cr)) < 0) &&
 706             (error = socket_getopt_common(so, level, option_name, optval,
 707             optlenp, flags)) < 0) {
 708                 error = (*so->so_downcalls->sd_getsockopt)
 709                     (so->so_proto_handle, level, option_name, optval, optlenp,
 710                     cr);
 711                 if (error ==  ENOPROTOOPT) {
 712                         if (level == SOL_SOCKET) {
 713                                 /*
 714                                  * If a protocol does not support a particular
 715                                  * socket option, set can fail (not allowed)
 716                                  * but get can not fail. This is the previous
 717                                  * sockfs bahvior.
 718                                  */
 719                                 switch (option_name) {
 720                                 case SO_LINGER:


 769                                 }
 770                         }
 771                 }
 772         }
 773 
 774         SO_UNBLOCK_FALLBACK(so);
 775         return (error);
 776 }
 777 
 778 int
 779 so_setsockopt(struct sonode *so, int level, int option_name,
 780     const void *optval, socklen_t optlen, struct cred *cr)
 781 {
 782         int error = 0;
 783         struct timeval tl;
 784         const void *opt = optval;
 785 
 786         if (level == SOL_FILTER)
 787                 return (sof_setsockopt(so, option_name, optval, optlen, cr));
 788 
 789         SO_BLOCK_FALLBACK_SAFE(so,
 790             SOP_SETSOCKOPT(so, level, option_name, optval, optlen, cr));
 791 
 792         /* X/Open requires this check */
 793         if (so->so_state & SS_CANTSENDMORE && !xnet_skip_checks) {
 794                 SO_UNBLOCK_FALLBACK(so);
 795                 if (xnet_check_print)
 796                         printf("sockfs: X/Open setsockopt check => EINVAL\n");
 797                 return (EINVAL);
 798         }
 799 
 800         if (so->so_filter_active > 0 &&
 801             (error = sof_filter_setsockopt(so, level, option_name,
 802             (void *)optval, &optlen, cr)) >= 0)
 803                 goto done;
 804 
 805         if (level == SOL_SOCKET) {
 806                 switch (option_name) {
 807                 case SO_RCVTIMEO:
 808                 case SO_SNDTIMEO: {
 809                         /*


 854         }
 855         error = (*so->so_downcalls->sd_setsockopt)
 856             (so->so_proto_handle, level, option_name, opt, optlen, cr);
 857 done:
 858         SO_UNBLOCK_FALLBACK(so);
 859         return (error);
 860 }
 861 
 862 int
 863 so_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode,
 864     struct cred *cr, int32_t *rvalp)
 865 {
 866         int error = 0;
 867 
 868         SO_BLOCK_FALLBACK(so, SOP_IOCTL(so, cmd, arg, mode, cr, rvalp));
 869 
 870         /*
 871          * If there is a pending error, return error
 872          * This can happen if a non blocking operation caused an error.
 873          */
 874         if (so->so_error != 0 && (so->so_mode & SM_DEFERERR) == 0) {
 875                 mutex_enter(&so->so_lock);
 876                 error = sogeterr(so, B_TRUE);
 877                 mutex_exit(&so->so_lock);
 878                 if (error != 0)
 879                         goto done;
 880         }
 881 
 882         /*
 883          * calling strioc can result in the socket falling back to TPI,
 884          * if that is supported.
 885          */
 886         if ((so->so_filter_active == 0 ||
 887             (error = sof_filter_ioctl(so, cmd, arg, mode,
 888             rvalp, cr)) < 0) &&
 889             (error = socket_ioctl_common(so, cmd, arg, mode, cr, rvalp)) < 0 &&
 890             (error = socket_strioc_common(so, cmd, arg, mode, cr, rvalp)) < 0) {
 891                 error = (*so->so_downcalls->sd_ioctl)(so->so_proto_handle,
 892                     cmd, arg, mode, rvalp, cr);
 893         }
 894