Print this page
3942 inject sanity into ipadm tcp buffer size properties
3943 _snd_lowat_fraction tcp tunable has no effect
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Peng Dai <peng.dai@delphix.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 1990 Mentat Inc.

  24  */
  25 
  26 /*
  27  * This file contains the interface control functions for IP.
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/stream.h>
  32 #include <sys/dlpi.h>
  33 #include <sys/stropts.h>
  34 #include <sys/strsun.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/strsubr.h>
  37 #include <sys/strlog.h>
  38 #include <sys/ddi.h>
  39 #include <sys/sunddi.h>
  40 #include <sys/cmn_err.h>
  41 #include <sys/kstat.h>
  42 #include <sys/debug.h>
  43 #include <sys/zone.h>


8837                     (flags & MOD_PROP_POSSIBLE) != MOD_PROP_POSSIBLE &&
8838                     (flags & MOD_PROP_PERM) != MOD_PROP_PERM)
8839                         return (B_FALSE);
8840         }
8841 
8842         return (B_TRUE);
8843 }
8844 
8845 /*
8846  * process the SIOC{SET|GET}PROP ioctl's
8847  */
8848 /* ARGSUSED */
8849 static void
8850 ip_sioctl_getsetprop(queue_t *q, mblk_t *mp)
8851 {
8852         struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8853         mblk_t          *mp1 = mp->b_cont;
8854         mod_ioc_prop_t  *pioc;
8855         mod_prop_info_t *ptbl = NULL, *pinfo = NULL;
8856         ip_stack_t      *ipst;
8857         icmp_stack_t    *is;
8858         tcp_stack_t     *tcps;
8859         sctp_stack_t    *sctps;
8860         udp_stack_t     *us;
8861         netstack_t      *stack;
8862         void            *cbarg;
8863         cred_t          *cr;
8864         boolean_t       set;
8865         int             err;
8866 
8867         ASSERT(q->q_next == NULL);
8868         ASSERT(CONN_Q(q));
8869 
8870         if (!getset_ioctl_checks(mp)) {
8871                 miocnak(q, mp, 0, EINVAL);
8872                 return;
8873         }
8874         ipst = CONNQ_TO_IPST(q);
8875         stack = ipst->ips_netstack;
8876         pioc = (mod_ioc_prop_t *)mp1->b_rptr;
8877 
8878         switch (pioc->mpr_proto) {
8879         case MOD_PROTO_IP:
8880         case MOD_PROTO_IPV4:
8881         case MOD_PROTO_IPV6:
8882                 ptbl = ipst->ips_propinfo_tbl;
8883                 cbarg = ipst;
8884                 break;
8885         case MOD_PROTO_RAWIP:
8886                 is = stack->netstack_icmp;
8887                 ptbl = is->is_propinfo_tbl;
8888                 cbarg = is;
8889                 break;
8890         case MOD_PROTO_TCP:
8891                 tcps = stack->netstack_tcp;
8892                 ptbl = tcps->tcps_propinfo_tbl;
8893                 cbarg = tcps;
8894                 break;
8895         case MOD_PROTO_UDP:
8896                 us = stack->netstack_udp;
8897                 ptbl = us->us_propinfo_tbl;
8898                 cbarg = us;
8899                 break;
8900         case MOD_PROTO_SCTP:
8901                 sctps = stack->netstack_sctp;
8902                 ptbl = sctps->sctps_propinfo_tbl;
8903                 cbarg = sctps;
8904                 break;
8905         default:
8906                 miocnak(q, mp, 0, EINVAL);
8907                 return;
8908         }
8909 
8910         /* search for given property in respective protocol propinfo table */
8911         for (pinfo = ptbl; pinfo->mpi_name != NULL; pinfo++) {
8912                 if (strcmp(pinfo->mpi_name, pioc->mpr_name) == 0 &&
8913                     pinfo->mpi_proto == pioc->mpr_proto)
8914                         break;
8915         }
8916         if (pinfo->mpi_name == NULL) {
8917                 miocnak(q, mp, 0, ENOENT);
8918                 return;
8919         }
8920 
8921         set = (iocp->ioc_cmd == SIOCSETPROP) ? B_TRUE : B_FALSE;
8922         if (set && pinfo->mpi_setf != NULL) {
8923                 cr = msg_getcred(mp, NULL);
8924                 if (cr == NULL)
8925                         cr = iocp->ioc_cr;
8926                 err = pinfo->mpi_setf(cbarg, cr, pinfo, pioc->mpr_ifname,
8927                     pioc->mpr_val, pioc->mpr_flags);
8928         } else if (!set && pinfo->mpi_getf != NULL) {
8929                 err = pinfo->mpi_getf(cbarg, pinfo, pioc->mpr_ifname,
8930                     pioc->mpr_val, pioc->mpr_valsize, pioc->mpr_flags);
8931         } else {
8932                 err = EPERM;
8933         }
8934 
8935         if (err != 0) {
8936                 miocnak(q, mp, 0, err);
8937         } else {
8938                 if (set)
8939                         miocack(q, mp, 0, 0);
8940                 else    /* For get, we need to return back the data */
8941                         miocack(q, mp, iocp->ioc_count, 0);
8942         }
8943 }
8944 
8945 /*
8946  * process the legacy ND_GET, ND_SET ioctl just for {ip|ip6}_forwarding
8947  * as several routing daemons have unfortunately used this 'unpublished'
8948  * but well-known ioctls.
8949  */
8950 /* ARGSUSED */
8951 static void
8952 ip_process_legacy_nddprop(queue_t *q, mblk_t *mp)
8953 {
8954         struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8955         mblk_t          *mp1 = mp->b_cont;
8956         char            *pname, *pval, *buf;
8957         uint_t          bufsize, proto;
8958         mod_prop_info_t *ptbl = NULL, *pinfo = NULL;
8959         ip_stack_t      *ipst;
8960         int             err = 0;
8961 
8962         ASSERT(CONN_Q(q));
8963         ipst = CONNQ_TO_IPST(q);
8964 
8965         if (iocp->ioc_count == 0 || mp1 == NULL) {
8966                 miocnak(q, mp, 0, EINVAL);
8967                 return;
8968         }
8969 
8970         mp1->b_datap->db_lim[-1] = '\0';  /* Force null termination */
8971         pval = buf = pname = (char *)mp1->b_rptr;
8972         bufsize = MBLKL(mp1);
8973 
8974         if (strcmp(pname, "ip_forwarding") == 0) {
8975                 pname = "forwarding";
8976                 proto = MOD_PROTO_IPV4;
8977         } else if (strcmp(pname, "ip6_forwarding") == 0) {
8978                 pname = "forwarding";
8979                 proto = MOD_PROTO_IPV6;
8980         } else {
8981                 miocnak(q, mp, 0, EINVAL);
8982                 return;
8983         }
8984 
8985         ptbl = ipst->ips_propinfo_tbl;
8986         for (pinfo = ptbl; pinfo->mpi_name != NULL; pinfo++) {
8987                 if (strcmp(pinfo->mpi_name, pname) == 0 &&
8988                     pinfo->mpi_proto == proto)
8989                         break;
8990         }
8991 
8992         ASSERT(pinfo->mpi_name != NULL);
8993 
8994         switch (iocp->ioc_cmd) {
8995         case ND_GET:
8996                 if ((err = pinfo->mpi_getf(ipst, pinfo, NULL, buf, bufsize,
8997                     0)) == 0) {
8998                         miocack(q, mp, iocp->ioc_count, 0);
8999                         return;
9000                 }
9001                 break;
9002         case ND_SET:
9003                 /*
9004                  * buffer will have property name and value in the following
9005                  * format,
9006                  * <property name>'\0'<property value>'\0', extract them;
9007                  */
9008                 while (*pval++)
9009                         noop;
9010 
9011                 if (!*pval || pval >= (char *)mp1->b_wptr) {
9012                         err = EINVAL;
9013                 } else if ((err = pinfo->mpi_setf(ipst, NULL, pinfo, NULL,
9014                     pval, 0)) == 0) {
9015                         miocack(q, mp, 0, 0);
9016                         return;
9017                 }
9018                 break;
9019         default:
9020                 err = EINVAL;
9021                 break;
9022         }
9023         miocnak(q, mp, 0, err);
9024 }
9025 
9026 /*
9027  * Wrapper function for resuming deferred ioctl processing
9028  * Used for SIOCGDSTINFO, SIOCGIP6ADDRPOLICY, SIOCGMSFILTER,
9029  * SIOCSMSFILTER, SIOCGIPMSFILTER, and SIOCSIPMSFILTER currently.
9030  */
9031 /* ARGSUSED */
9032 void
9033 ip_sioctl_copyin_resume(ipsq_t *dummy_ipsq, queue_t *q, mblk_t *mp,
9034     void *dummy_arg)




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 1990 Mentat Inc.
  24  * Copyright (c) 2013 by Delphix. All rights reserved.
  25  */
  26 
  27 /*
  28  * This file contains the interface control functions for IP.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/stream.h>
  33 #include <sys/dlpi.h>
  34 #include <sys/stropts.h>
  35 #include <sys/strsun.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/strsubr.h>
  38 #include <sys/strlog.h>
  39 #include <sys/ddi.h>
  40 #include <sys/sunddi.h>
  41 #include <sys/cmn_err.h>
  42 #include <sys/kstat.h>
  43 #include <sys/debug.h>
  44 #include <sys/zone.h>


8838                     (flags & MOD_PROP_POSSIBLE) != MOD_PROP_POSSIBLE &&
8839                     (flags & MOD_PROP_PERM) != MOD_PROP_PERM)
8840                         return (B_FALSE);
8841         }
8842 
8843         return (B_TRUE);
8844 }
8845 
8846 /*
8847  * process the SIOC{SET|GET}PROP ioctl's
8848  */
8849 /* ARGSUSED */
8850 static void
8851 ip_sioctl_getsetprop(queue_t *q, mblk_t *mp)
8852 {
8853         struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8854         mblk_t          *mp1 = mp->b_cont;
8855         mod_ioc_prop_t  *pioc;
8856         mod_prop_info_t *ptbl = NULL, *pinfo = NULL;
8857         ip_stack_t      *ipst;




8858         netstack_t      *stack;

8859         cred_t          *cr;
8860         boolean_t       set;
8861         int             err;
8862 
8863         ASSERT(q->q_next == NULL);
8864         ASSERT(CONN_Q(q));
8865 
8866         if (!getset_ioctl_checks(mp)) {
8867                 miocnak(q, mp, 0, EINVAL);
8868                 return;
8869         }
8870         ipst = CONNQ_TO_IPST(q);
8871         stack = ipst->ips_netstack;
8872         pioc = (mod_ioc_prop_t *)mp1->b_rptr;
8873 
8874         switch (pioc->mpr_proto) {
8875         case MOD_PROTO_IP:
8876         case MOD_PROTO_IPV4:
8877         case MOD_PROTO_IPV6:
8878                 ptbl = ipst->ips_propinfo_tbl;

8879                 break;
8880         case MOD_PROTO_RAWIP:
8881                 ptbl = stack->netstack_icmp->is_propinfo_tbl;


8882                 break;
8883         case MOD_PROTO_TCP:
8884                 ptbl = stack->netstack_tcp->tcps_propinfo_tbl;


8885                 break;
8886         case MOD_PROTO_UDP:
8887                 ptbl = stack->netstack_udp->us_propinfo_tbl;


8888                 break;
8889         case MOD_PROTO_SCTP:
8890                 ptbl = stack->netstack_sctp->sctps_propinfo_tbl;


8891                 break;
8892         default:
8893                 miocnak(q, mp, 0, EINVAL);
8894                 return;
8895         }
8896 
8897         pinfo = mod_prop_lookup(ptbl, pioc->mpr_name, pioc->mpr_proto);
8898         if (pinfo == NULL) {





8899                 miocnak(q, mp, 0, ENOENT);
8900                 return;
8901         }
8902 
8903         set = (iocp->ioc_cmd == SIOCSETPROP) ? B_TRUE : B_FALSE;
8904         if (set && pinfo->mpi_setf != NULL) {
8905                 cr = msg_getcred(mp, NULL);
8906                 if (cr == NULL)
8907                         cr = iocp->ioc_cr;
8908                 err = pinfo->mpi_setf(stack, cr, pinfo, pioc->mpr_ifname,
8909                     pioc->mpr_val, pioc->mpr_flags);
8910         } else if (!set && pinfo->mpi_getf != NULL) {
8911                 err = pinfo->mpi_getf(stack, pinfo, pioc->mpr_ifname,
8912                     pioc->mpr_val, pioc->mpr_valsize, pioc->mpr_flags);
8913         } else {
8914                 err = EPERM;
8915         }
8916 
8917         if (err != 0) {
8918                 miocnak(q, mp, 0, err);
8919         } else {
8920                 if (set)
8921                         miocack(q, mp, 0, 0);
8922                 else    /* For get, we need to return back the data */
8923                         miocack(q, mp, iocp->ioc_count, 0);
8924         }
8925 }
8926 
8927 /*
8928  * process the legacy ND_GET, ND_SET ioctl just for {ip|ip6}_forwarding
8929  * as several routing daemons have unfortunately used this 'unpublished'
8930  * but well-known ioctls.
8931  */
8932 /* ARGSUSED */
8933 static void
8934 ip_process_legacy_nddprop(queue_t *q, mblk_t *mp)
8935 {
8936         struct iocblk   *iocp = (struct iocblk *)mp->b_rptr;
8937         mblk_t          *mp1 = mp->b_cont;
8938         char            *pname, *pval, *buf;
8939         uint_t          bufsize, proto;
8940         mod_prop_info_t *pinfo = NULL;
8941         ip_stack_t      *ipst;
8942         int             err = 0;
8943 
8944         ASSERT(CONN_Q(q));
8945         ipst = CONNQ_TO_IPST(q);
8946 
8947         if (iocp->ioc_count == 0 || mp1 == NULL) {
8948                 miocnak(q, mp, 0, EINVAL);
8949                 return;
8950         }
8951 
8952         mp1->b_datap->db_lim[-1] = '\0';  /* Force null termination */
8953         pval = buf = pname = (char *)mp1->b_rptr;
8954         bufsize = MBLKL(mp1);
8955 
8956         if (strcmp(pname, "ip_forwarding") == 0) {
8957                 pname = "forwarding";
8958                 proto = MOD_PROTO_IPV4;
8959         } else if (strcmp(pname, "ip6_forwarding") == 0) {
8960                 pname = "forwarding";
8961                 proto = MOD_PROTO_IPV6;
8962         } else {
8963                 miocnak(q, mp, 0, EINVAL);
8964                 return;
8965         }
8966 
8967         pinfo = mod_prop_lookup(ipst->ips_propinfo_tbl, pname, proto);





8968 


8969         switch (iocp->ioc_cmd) {
8970         case ND_GET:
8971                 if ((err = pinfo->mpi_getf(ipst->ips_netstack, pinfo, NULL, buf,
8972                     bufsize, 0)) == 0) {
8973                         miocack(q, mp, iocp->ioc_count, 0);
8974                         return;
8975                 }
8976                 break;
8977         case ND_SET:
8978                 /*
8979                  * buffer will have property name and value in the following
8980                  * format,
8981                  * <property name>'\0'<property value>'\0', extract them;
8982                  */
8983                 while (*pval++)
8984                         noop;
8985 
8986                 if (!*pval || pval >= (char *)mp1->b_wptr) {
8987                         err = EINVAL;
8988                 } else if ((err = pinfo->mpi_setf(ipst->ips_netstack, NULL,
8989                     pinfo, NULL, pval, 0)) == 0) {
8990                         miocack(q, mp, 0, 0);
8991                         return;
8992                 }
8993                 break;
8994         default:
8995                 err = EINVAL;
8996                 break;
8997         }
8998         miocnak(q, mp, 0, err);
8999 }
9000 
9001 /*
9002  * Wrapper function for resuming deferred ioctl processing
9003  * Used for SIOCGDSTINFO, SIOCGIP6ADDRPOLICY, SIOCGMSFILTER,
9004  * SIOCSMSFILTER, SIOCGIPMSFILTER, and SIOCSIPMSFILTER currently.
9005  */
9006 /* ARGSUSED */
9007 void
9008 ip_sioctl_copyin_resume(ipsq_t *dummy_ipsq, queue_t *q, mblk_t *mp,
9009     void *dummy_arg)