usr/src/uts/common/inet/udp/udp.c
changeset 11537 8eca52188202
parent 11134 8aa0c4ca6639
child 11680 f7d6d87905e0
equal deleted inserted replaced
11536:4c36e6a8710f 11537:8eca52188202
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    18  *
    18  *
    19  * CDDL HEADER END
    19  * CDDL HEADER END
    20  */
    20  */
    21 /*
    21 /*
    22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
    22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
    23  * Use is subject to license terms.
    23  * Use is subject to license terms.
    24  */
    24  */
    25 /* Copyright (c) 1990 Mentat Inc. */
    25 /* Copyright (c) 1990 Mentat Inc. */
    26 
    26 
    27 #include <sys/types.h>
    27 #include <sys/types.h>
   196 
   196 
   197 /* Common routines for TPI and socket module */
   197 /* Common routines for TPI and socket module */
   198 static void	udp_ulp_recv(conn_t *, mblk_t *, uint_t, ip_recv_attr_t *);
   198 static void	udp_ulp_recv(conn_t *, mblk_t *, uint_t, ip_recv_attr_t *);
   199 
   199 
   200 /* Common routine for TPI and socket module */
   200 /* Common routine for TPI and socket module */
   201 static conn_t	*udp_do_open(cred_t *, boolean_t, int);
   201 static conn_t	*udp_do_open(cred_t *, boolean_t, int, int *);
   202 static void	udp_do_close(conn_t *);
   202 static void	udp_do_close(conn_t *);
   203 static int	udp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
   203 static int	udp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
   204     boolean_t);
   204     boolean_t);
   205 static int	udp_do_unbind(conn_t *);
   205 static int	udp_do_unbind(conn_t *);
   206 
   206 
  1513 {
  1513 {
  1514 	udp_t		*udp;
  1514 	udp_t		*udp;
  1515 	conn_t		*connp;
  1515 	conn_t		*connp;
  1516 	dev_t		conn_dev;
  1516 	dev_t		conn_dev;
  1517 	vmem_t		*minor_arena;
  1517 	vmem_t		*minor_arena;
       
  1518 	int		err;
  1518 
  1519 
  1519 	/* If the stream is already open, return immediately. */
  1520 	/* If the stream is already open, return immediately. */
  1520 	if (q->q_ptr != NULL)
  1521 	if (q->q_ptr != NULL)
  1521 		return (0);
  1522 		return (0);
  1522 
  1523 
  1547 		WR(q)->q_ptr = (void *)minor_arena;
  1548 		WR(q)->q_ptr = (void *)minor_arena;
  1548 		qprocson(q);
  1549 		qprocson(q);
  1549 		return (0);
  1550 		return (0);
  1550 	}
  1551 	}
  1551 
  1552 
  1552 	connp = udp_do_open(credp, isv6, KM_SLEEP);
  1553 	connp = udp_do_open(credp, isv6, KM_SLEEP, &err);
  1553 	if (connp == NULL) {
  1554 	if (connp == NULL) {
  1554 		inet_minor_free(minor_arena, conn_dev);
  1555 		inet_minor_free(minor_arena, conn_dev);
  1555 		return (ENOMEM);
  1556 		return (err);
  1556 	}
  1557 	}
  1557 	udp = connp->conn_udp;
  1558 	udp = connp->conn_udp;
  1558 
  1559 
  1559 	*devp = makedevice(getemajor(*devp), (minor_t)conn_dev);
  1560 	*devp = makedevice(getemajor(*devp), (minor_t)conn_dev);
  1560 	connp->conn_dev = conn_dev;
  1561 	connp->conn_dev = conn_dev;
  5049 /*
  5050 /*
  5050  * Below routines for UDP socket module.
  5051  * Below routines for UDP socket module.
  5051  */
  5052  */
  5052 
  5053 
  5053 static conn_t *
  5054 static conn_t *
  5054 udp_do_open(cred_t *credp, boolean_t isv6, int flags)
  5055 udp_do_open(cred_t *credp, boolean_t isv6, int flags, int *errorp)
  5055 {
  5056 {
  5056 	udp_t		*udp;
  5057 	udp_t		*udp;
  5057 	conn_t		*connp;
  5058 	conn_t		*connp;
  5058 	zoneid_t 	zoneid;
  5059 	zoneid_t 	zoneid;
  5059 	netstack_t 	*ns;
  5060 	netstack_t 	*ns;
  5060 	udp_stack_t 	*us;
  5061 	udp_stack_t 	*us;
  5061 	int		len;
  5062 	int		len;
  5062 
  5063 
       
  5064 	ASSERT(errorp != NULL);
       
  5065 
       
  5066 	if ((*errorp = secpolicy_basic_net_access(credp)) != 0)
       
  5067 		return (NULL);
       
  5068 
  5063 	ns = netstack_find_by_cred(credp);
  5069 	ns = netstack_find_by_cred(credp);
  5064 	ASSERT(ns != NULL);
  5070 	ASSERT(ns != NULL);
  5065 	us = ns->netstack_udp;
  5071 	us = ns->netstack_udp;
  5066 	ASSERT(us != NULL);
  5072 	ASSERT(us != NULL);
  5067 
  5073 
  5077 	ASSERT(flags == KM_SLEEP || flags == KM_NOSLEEP);
  5083 	ASSERT(flags == KM_SLEEP || flags == KM_NOSLEEP);
  5078 
  5084 
  5079 	connp = ipcl_conn_create(IPCL_UDPCONN, flags, ns);
  5085 	connp = ipcl_conn_create(IPCL_UDPCONN, flags, ns);
  5080 	if (connp == NULL) {
  5086 	if (connp == NULL) {
  5081 		netstack_rele(ns);
  5087 		netstack_rele(ns);
       
  5088 		*errorp = ENOMEM;
  5082 		return (NULL);
  5089 		return (NULL);
  5083 	}
  5090 	}
  5084 	udp = connp->conn_udp;
  5091 	udp = connp->conn_udp;
  5085 
  5092 
  5086 	/*
  5093 	/*
  5181 	if (family == AF_INET6)
  5188 	if (family == AF_INET6)
  5182 		isv6 = B_TRUE;
  5189 		isv6 = B_TRUE;
  5183 	else
  5190 	else
  5184 		isv6 = B_FALSE;
  5191 		isv6 = B_FALSE;
  5185 
  5192 
  5186 	connp = udp_do_open(credp, isv6, flags);
  5193 	connp = udp_do_open(credp, isv6, flags, errorp);
  5187 	if (connp == NULL) {
  5194 	if (connp == NULL)
  5188 		*errorp = ENOMEM;
       
  5189 		return (NULL);
  5195 		return (NULL);
  5190 	}
       
  5191 
  5196 
  5192 	udp = connp->conn_udp;
  5197 	udp = connp->conn_udp;
  5193 	ASSERT(udp != NULL);
  5198 	ASSERT(udp != NULL);
  5194 	us = udp->udp_us;
  5199 	us = udp->udp_us;
  5195 	ASSERT(us != NULL);
  5200 	ASSERT(us != NULL);