3 *
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 */
24 /* Copyright (c) 1990 Mentat Inc. */
25
26 #include <sys/types.h>
27 #include <sys/stream.h>
28 #include <sys/stropts.h>
29 #include <sys/strlog.h>
30 #include <sys/strsun.h>
31 #define _SUN_TPI_VERSION 2
32 #include <sys/tihdr.h>
33 #include <sys/timod.h>
34 #include <sys/ddi.h>
35 #include <sys/sunddi.h>
36 #include <sys/strsubr.h>
37 #include <sys/suntpi.h>
38 #include <sys/xti_inet.h>
39 #include <sys/cmn_err.h>
40 #include <sys/kmem.h>
41 #include <sys/cred.h>
42 #include <sys/policy.h>
75 #include <inet/ipclassifier.h>
76
77 #include <sys/tsol/label.h>
78 #include <sys/tsol/tnet.h>
79
80 #include <inet/rawip_impl.h>
81
82 #include <sys/disp.h>
83
84 /*
85 * Synchronization notes:
86 *
87 * RAWIP is MT and uses the usual kernel synchronization primitives. We use
88 * conn_lock to protect the icmp_t.
89 *
90 * Plumbing notes:
91 * ICMP is always a device driver. For compatibility with mibopen() code
92 * it is possible to I_PUSH "icmp", but that results in pushing a passthrough
93 * dummy module.
94 */
95
96 static void icmp_addr_req(queue_t *q, mblk_t *mp);
97 static void icmp_tpi_bind(queue_t *q, mblk_t *mp);
98 static void icmp_bind_proto(icmp_t *icmp);
99 static int icmp_build_hdr_template(conn_t *, const in6_addr_t *,
100 const in6_addr_t *, uint32_t);
101 static void icmp_capability_req(queue_t *q, mblk_t *mp);
102 static int icmp_close(queue_t *q, int flags);
103 static void icmp_close_free(conn_t *);
104 static void icmp_tpi_connect(queue_t *q, mblk_t *mp);
105 static void icmp_tpi_disconnect(queue_t *q, mblk_t *mp);
106 static void icmp_err_ack(queue_t *q, mblk_t *mp, t_scalar_t t_error,
107 int sys_error);
108 static void icmp_err_ack_prim(queue_t *q, mblk_t *mp, t_scalar_t primitive,
109 t_scalar_t tlierr, int sys_error);
110 static void icmp_icmp_input(void *arg1, mblk_t *mp, void *arg2,
111 ip_recv_attr_t *);
112 static void icmp_icmp_error_ipv6(conn_t *connp, mblk_t *mp,
113 ip_recv_attr_t *);
114 static void icmp_info_req(queue_t *q, mblk_t *mp);
115 static void icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
196 /* For AF_INET6 aka /dev/icmp6 */
197 struct streamtab icmpinfov6 = {
198 &icmprinitv6, &icmpwinit
199 };
200
201 /* Default structure copied into T_INFO_ACK messages */
202 static struct T_info_ack icmp_g_t_info_ack = {
203 T_INFO_ACK,
204 IP_MAXPACKET, /* TSDU_size. icmp allows maximum size messages. */
205 T_INVALID, /* ETSDU_size. icmp does not support expedited data. */
206 T_INVALID, /* CDATA_size. icmp does not support connect data. */
207 T_INVALID, /* DDATA_size. icmp does not support disconnect data. */
208 0, /* ADDR_size - filled in later. */
209 0, /* OPT_size - not initialized here */
210 IP_MAXPACKET, /* TIDU_size. icmp allows maximum size messages. */
211 T_CLTS, /* SERV_type. icmp supports connection-less. */
212 TS_UNBND, /* CURRENT_state. This is set from icmp_state. */
213 (XPG4_1|SENDZERO) /* PROVIDER_flag */
214 };
215
216 /*
217 * All of these are alterable, within the min/max values given, at run time.
218 *
219 * Note: All those tunables which do not start with "icmp_" are Committed and
220 * therefore are public. See PSARC 2010/080.
221 */
222 static mod_prop_info_t icmp_propinfo_tbl[] = {
223 /* tunable - 0 */
224 { "_wroff_extra", MOD_PROTO_RAWIP,
225 mod_set_uint32, mod_get_uint32,
226 {0, 128, 32}, {32} },
227
228 { "_ipv4_ttl", MOD_PROTO_RAWIP,
229 mod_set_uint32, mod_get_uint32,
230 {1, 255, 255}, {255} },
231
232 { "_ipv6_hoplimit", MOD_PROTO_RAWIP,
233 mod_set_uint32, mod_get_uint32,
234 {0, IPV6_MAX_HOPS, IPV6_DEFAULT_HOPS},
235 {IPV6_DEFAULT_HOPS} },
236
237 { "_bsd_compat", MOD_PROTO_RAWIP,
238 mod_set_boolean, mod_get_boolean,
239 {B_TRUE}, {B_TRUE} },
240
241 { "send_maxbuf", MOD_PROTO_RAWIP,
242 mod_set_uint32, mod_get_uint32,
243 {4096, 65536, 8192}, {8192} },
244
245 { "_xmit_lowat", MOD_PROTO_RAWIP,
246 mod_set_uint32, mod_get_uint32,
247 {0, 65536, 1024}, {1024} },
248
249 { "recv_maxbuf", MOD_PROTO_RAWIP,
250 mod_set_uint32, mod_get_uint32,
251 {4096, 65536, 8192}, {8192} },
252
253 { "_max_buf", MOD_PROTO_RAWIP,
254 mod_set_uint32, mod_get_uint32,
255 {65536, 1024*1024*1024, 256*1024}, {256 * 1024} },
256
257 { "_pmtu_discovery", MOD_PROTO_RAWIP,
258 mod_set_boolean, mod_get_boolean,
259 {B_FALSE}, {B_FALSE} },
260
261 { "_sendto_ignerr", MOD_PROTO_RAWIP,
262 mod_set_boolean, mod_get_boolean,
263 {B_FALSE}, {B_FALSE} },
264
265 { "?", MOD_PROTO_RAWIP, NULL, mod_get_allprop, {0}, {0} },
266
267 { NULL, 0, NULL, NULL, {0}, {0} }
268 };
269
270 #define is_wroff_extra is_propinfo_tbl[0].prop_cur_uval
271 #define is_ipv4_ttl is_propinfo_tbl[1].prop_cur_uval
272 #define is_ipv6_hoplimit is_propinfo_tbl[2].prop_cur_uval
273 #define is_bsd_compat is_propinfo_tbl[3].prop_cur_bval
274 #define is_xmit_hiwat is_propinfo_tbl[4].prop_cur_uval
275 #define is_xmit_lowat is_propinfo_tbl[5].prop_cur_uval
|
3 *
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) 2013 by Delphix. All rights reserved.
24 */
25 /* Copyright (c) 1990 Mentat Inc. */
26
27 #include <sys/types.h>
28 #include <sys/stream.h>
29 #include <sys/stropts.h>
30 #include <sys/strlog.h>
31 #include <sys/strsun.h>
32 #define _SUN_TPI_VERSION 2
33 #include <sys/tihdr.h>
34 #include <sys/timod.h>
35 #include <sys/ddi.h>
36 #include <sys/sunddi.h>
37 #include <sys/strsubr.h>
38 #include <sys/suntpi.h>
39 #include <sys/xti_inet.h>
40 #include <sys/cmn_err.h>
41 #include <sys/kmem.h>
42 #include <sys/cred.h>
43 #include <sys/policy.h>
76 #include <inet/ipclassifier.h>
77
78 #include <sys/tsol/label.h>
79 #include <sys/tsol/tnet.h>
80
81 #include <inet/rawip_impl.h>
82
83 #include <sys/disp.h>
84
85 /*
86 * Synchronization notes:
87 *
88 * RAWIP is MT and uses the usual kernel synchronization primitives. We use
89 * conn_lock to protect the icmp_t.
90 *
91 * Plumbing notes:
92 * ICMP is always a device driver. For compatibility with mibopen() code
93 * it is possible to I_PUSH "icmp", but that results in pushing a passthrough
94 * dummy module.
95 */
96 static void icmp_addr_req(queue_t *q, mblk_t *mp);
97 static void icmp_tpi_bind(queue_t *q, mblk_t *mp);
98 static void icmp_bind_proto(icmp_t *icmp);
99 static int icmp_build_hdr_template(conn_t *, const in6_addr_t *,
100 const in6_addr_t *, uint32_t);
101 static void icmp_capability_req(queue_t *q, mblk_t *mp);
102 static int icmp_close(queue_t *q, int flags);
103 static void icmp_close_free(conn_t *);
104 static void icmp_tpi_connect(queue_t *q, mblk_t *mp);
105 static void icmp_tpi_disconnect(queue_t *q, mblk_t *mp);
106 static void icmp_err_ack(queue_t *q, mblk_t *mp, t_scalar_t t_error,
107 int sys_error);
108 static void icmp_err_ack_prim(queue_t *q, mblk_t *mp, t_scalar_t primitive,
109 t_scalar_t tlierr, int sys_error);
110 static void icmp_icmp_input(void *arg1, mblk_t *mp, void *arg2,
111 ip_recv_attr_t *);
112 static void icmp_icmp_error_ipv6(conn_t *connp, mblk_t *mp,
113 ip_recv_attr_t *);
114 static void icmp_info_req(queue_t *q, mblk_t *mp);
115 static void icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
196 /* For AF_INET6 aka /dev/icmp6 */
197 struct streamtab icmpinfov6 = {
198 &icmprinitv6, &icmpwinit
199 };
200
201 /* Default structure copied into T_INFO_ACK messages */
202 static struct T_info_ack icmp_g_t_info_ack = {
203 T_INFO_ACK,
204 IP_MAXPACKET, /* TSDU_size. icmp allows maximum size messages. */
205 T_INVALID, /* ETSDU_size. icmp does not support expedited data. */
206 T_INVALID, /* CDATA_size. icmp does not support connect data. */
207 T_INVALID, /* DDATA_size. icmp does not support disconnect data. */
208 0, /* ADDR_size - filled in later. */
209 0, /* OPT_size - not initialized here */
210 IP_MAXPACKET, /* TIDU_size. icmp allows maximum size messages. */
211 T_CLTS, /* SERV_type. icmp supports connection-less. */
212 TS_UNBND, /* CURRENT_state. This is set from icmp_state. */
213 (XPG4_1|SENDZERO) /* PROVIDER_flag */
214 };
215
216 static int
217 icmp_set_buf_prop(netstack_t *stack, cred_t *cr, mod_prop_info_t *pinfo,
218 const char *ifname, const void *pval, uint_t flags)
219 {
220 return (mod_set_buf_prop(stack->netstack_icmp->is_propinfo_tbl,
221 stack, cr, pinfo, ifname, pval, flags));
222 }
223
224 static int
225 icmp_get_buf_prop(netstack_t *stack, mod_prop_info_t *pinfo, const char *ifname,
226 void *val, uint_t psize, uint_t flags)
227 {
228 return (mod_get_buf_prop(stack->netstack_icmp->is_propinfo_tbl, stack,
229 pinfo, ifname, val, psize, flags));
230 }
231
232 /*
233 * All of these are alterable, within the min/max values given, at run time.
234 *
235 * Note: All those tunables which do not start with "icmp_" are Committed and
236 * therefore are public. See PSARC 2010/080.
237 */
238 static mod_prop_info_t icmp_propinfo_tbl[] = {
239 /* tunable - 0 */
240 { "_wroff_extra", MOD_PROTO_RAWIP,
241 mod_set_uint32, mod_get_uint32,
242 {0, 128, 32}, {32} },
243
244 { "_ipv4_ttl", MOD_PROTO_RAWIP,
245 mod_set_uint32, mod_get_uint32,
246 {1, 255, 255}, {255} },
247
248 { "_ipv6_hoplimit", MOD_PROTO_RAWIP,
249 mod_set_uint32, mod_get_uint32,
250 {0, IPV6_MAX_HOPS, IPV6_DEFAULT_HOPS},
251 {IPV6_DEFAULT_HOPS} },
252
253 { "_bsd_compat", MOD_PROTO_RAWIP,
254 mod_set_boolean, mod_get_boolean,
255 {B_TRUE}, {B_TRUE} },
256
257 { "send_buf", MOD_PROTO_RAWIP,
258 icmp_set_buf_prop, icmp_get_buf_prop,
259 {4096, 65536, 8192}, {8192} },
260
261 { "_xmit_lowat", MOD_PROTO_RAWIP,
262 mod_set_uint32, mod_get_uint32,
263 {0, 65536, 1024}, {1024} },
264
265 { "recv_buf", MOD_PROTO_RAWIP,
266 icmp_set_buf_prop, icmp_get_buf_prop,
267 {4096, 65536, 8192}, {8192} },
268
269 { "max_buf", MOD_PROTO_RAWIP,
270 mod_set_uint32, mod_get_uint32,
271 {65536, ULP_MAX_BUF, 256*1024}, {256*1024} },
272
273 { "_pmtu_discovery", MOD_PROTO_RAWIP,
274 mod_set_boolean, mod_get_boolean,
275 {B_FALSE}, {B_FALSE} },
276
277 { "_sendto_ignerr", MOD_PROTO_RAWIP,
278 mod_set_boolean, mod_get_boolean,
279 {B_FALSE}, {B_FALSE} },
280
281 { "?", MOD_PROTO_RAWIP, NULL, mod_get_allprop, {0}, {0} },
282
283 { NULL, 0, NULL, NULL, {0}, {0} }
284 };
285
286 #define is_wroff_extra is_propinfo_tbl[0].prop_cur_uval
287 #define is_ipv4_ttl is_propinfo_tbl[1].prop_cur_uval
288 #define is_ipv6_hoplimit is_propinfo_tbl[2].prop_cur_uval
289 #define is_bsd_compat is_propinfo_tbl[3].prop_cur_bval
290 #define is_xmit_hiwat is_propinfo_tbl[4].prop_cur_uval
291 #define is_xmit_lowat is_propinfo_tbl[5].prop_cur_uval
|