Home | History | Annotate | Download | only in sockfs
      1 /*
      2  * CDDL HEADER START
      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 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/types.h>
     27 #include <sys/conf.h>
     28 #include <sys/modctl.h>
     29 #include <sys/stream.h>
     30 #include <sys/strsubr.h>
     31 #include <sys/stropts.h>
     32 #define	_SUN_TPI_VERSION 2
     33 #include <sys/ddi.h>
     34 #include <sys/sunddi.h>
     35 #include <sys/cmn_err.h>
     36 #include <sys/debug.h>
     37 #include <sys/vtrace.h>
     38 #include <sys/errno.h>
     39 #include <inet/common.h>
     40 #include <inet/led.h>
     41 #include <inet/mi.h>
     42 #include <inet/nd.h>
     43 #include <sys/strsun.h>
     44 
     45 #include <fs/sockfs/nl7c.h>
     46 #include <fs/sockfs/nl7curi.h>
     47 
     48 #include <inet/nca/nca.h>
     49 #include <inet/nca/ncalogd.h>
     50 
     51 /*
     52  * This file is for NCA compatability, specifically it provides ndd
     53  * support for existing NCA ndd ...
     54  */
     55 
     56 extern boolean_t	nl7c_logd_enabled;
     57 extern nca_fio_t	*nl7c_logd_fio;
     58 extern clock_t		nl7c_uri_ttl;
     59 extern boolean_t	nl7c_use_kmem;
     60 extern uint64_t		nl7c_file_prefetch;
     61 extern uint64_t		nl7c_uri_max;
     62 extern uint64_t		nl7c_uri_bytes;
     63 
     64 extern void		nl7c_mi_report_addr(mblk_t *);
     65 
     66 #define	MS	1L
     67 #define	SECONDS	(1000 * MS)
     68 #define	MINUTES	(60 * SECONDS)
     69 #define	HOURS	(60 * MINUTES)
     70 #define	DAYS	(24 * HOURS)
     71 
     72 #define	PARAM_MAX UINT_MAX
     73 #define	PARAML_MAX ULONG_MAX
     74 
     75 #include <inet/nca/ncandd.h>
     76 
     77 uint32_t nca_major_version = 1;
     78 uint32_t nca_minor_version = 3;
     79 uint32_t nca_httpd_version = NCA_HTTP_VERSION1;
     80 uint32_t nca_logd_version = NCA_LOG_VERSION1;
     81 
     82 caddr_t	nca_g_nd;	/* Head of 'named dispatch' variable list */
     83 
     84 /*
     85  * min, max, and value are int64_t's, addr is the optional address of an
     86  * external int64_t to be updated at init/set, name is the ndd name used
     87  * to access. Note, if min == max then only get is allowed, i.e. RO.
     88  */
     89 
     90 /* BEGIN CSTYLED */
     91 ncaparam_t	nca_param_arr[] = {
     92  /*min	max		value		name */
     93  { 0,	1,		1,		"nca_log_cycle"},
     94  { 0,	1,		0,		"no_caching"},
     95  { 0,	PARAML_MAX,    	0,		"nca_log_size"},
     96  { 0,	PARAM_MAX,     	10000000,	"nca_max_cache_size"},
     97  { 0,	PARAM_MAX,	300*SECONDS,	"nca_http_timeout"},
     98  { 0,	PARAM_MAX,	15*SECONDS,	"nca_http_keep_alive_timeout"},
     99  { 0,	PARAM_MAX,	100,		"nca_http_keep_alive_max"},
    100  { 0,	1,		1,		"nca_inq_nointr"},
    101  { 0,	1,		1,		"nca_use_hwcksum"},
    102  { 0,	PARAM_MAX,	0,		"nca_segmap_min_size"},
    103 };
    104 
    105 /*
    106  * Obsolete ip variables, use "/dev/ip" instead.
    107  */
    108 
    109 ncaparam_t	nca_ip_obsolete_arr[] = {
    110  { 0, 0, 0, "ip_forwarding"},
    111  { 0, 0, 0, "ip_respond_to_address_mask_broadcast"},
    112  { 0, 0, 0, "ip_respond_to_echo_broadcast"},
    113  { 0, 0, 0, "ip_respond_to_timestamp"},
    114  { 0, 0, 0, "ip_respond_to_timestamp_broadcast"},
    115  { 0, 0, 0, "ip_send_redirects"},
    116  { 0, 0, 0, "ip_forward_directed_broadcasts"},
    117  { 0, 0, 0, "ip_debug"},
    118  { 0, 0, 0, "ip_mrtdebug"},
    119  { 0, 0, 0, "ip_ire_cleanup_interval" },
    120  { 0, 0, 0, "ip_ire_flush_interval" },
    121  { 0, 0, 0, "ip_ire_redirect_interval" },
    122  { 0, 0, 0, "ip_def_ttl" },
    123  { 0, 0, 0, "ip_forward_src_routed"},
    124  { 0, 0, 0, "ip_wroff_extra" },
    125  { 0, 0, 0, "ip_ire_pathmtu_interval" },
    126  { 0, 0, 0, "ip_icmp_return_data_bytes" },
    127  { 0, 0, 0, "ip_send_source_quench" },
    128  { 0, 0, 0, "ip_path_mtu_discovery" },
    129  { 0, 0, 0, "ip_ignore_delete_time" },
    130  { 0, 0, 0, "ip_ignore_redirect" },
    131  { 0, 0, 0, "ip_output_queue" },
    132  { 0, 0, 0, "ip_broadcast_ttl" },
    133  { 0, 0, 0, "ip_icmp_err_interval" },
    134  { 0, 0, 0, "ip_reass_queue_bytes" },
    135  { 0, 0, 0, "ip_strict_dst_multihoming" },
    136  { 0, 0, 0, "ip_addrs_per_if"},
    137 };
    138 
    139 /*
    140  * Obsolete tcp variables, use "/dev/tcp" instead.
    141  */
    142 
    143 ncaparam_t	nca_tcp_obsolete_arr[] = {
    144  { 0, 0, 0, "tcp_time_wait_interval"},
    145  { 0, 0, 0, "tcp_conn_req_max_q" },
    146  { 0, 0, 0, "tcp_conn_req_max_q0" },
    147  { 0, 0, 0, "tcp_conn_req_min" },
    148  { 0, 0, 0, "tcp_conn_grace_period" },
    149  { 0, 0, 0, "tcp_cwnd_max" },
    150  { 0, 0, 0, "tcp_debug" },
    151  { 0, 0, 0, "tcp_smallest_nonpriv_port"},
    152  { 0, 0, 0, "tcp_ip_abort_cinterval"},
    153  { 0, 0, 0, "tcp_ip_abort_linterval"},
    154  { 0, 0, 0, "tcp_ip_abort_interval"},
    155  { 0, 0, 0, "tcp_ip_notify_cinterval"},
    156  { 0, 0, 0, "tcp_ip_notify_interval"},
    157  { 0, 0, 0, "tcp_ip_ttl"},
    158  { 0, 0, 0, "tcp_keepalive_interval"},
    159  { 0, 0, 0, "tcp_maxpsz_multiplier" },
    160  { 0, 0, 0, "tcp_mss_def"},
    161  { 0, 0, 0, "tcp_mss_max"},
    162  { 0, 0, 0, "tcp_mss_min"},
    163  { 0, 0, 0, "tcp_naglim_def"},
    164  { 0, 0, 0, "tcp_rexmit_interval_initial"},
    165  { 0, 0, 0, "tcp_rexmit_interval_max"},
    166  { 0, 0, 0, "tcp_rexmit_interval_min"},
    167  { 0, 0, 0, "tcp_wroff_xtra" },
    168  { 0, 0, 0, "tcp_deferred_ack_interval" },
    169  { 0, 0, 0, "tcp_snd_lowat_fraction" },
    170  { 0, 0, 0, "tcp_sth_rcv_hiwat" },
    171  { 0, 0, 0, "tcp_sth_rcv_lowat" },
    172  { 0, 0, 0, "tcp_dupack_fast_retransmit" },
    173  { 0, 0, 0, "tcp_ignore_path_mtu" },
    174  { 0, 0, 0, "tcp_rcv_push_wait" },
    175  { 0, 0, 0, "tcp_smallest_anon_port"},
    176  { 0, 0, 0, "tcp_largest_anon_port"},
    177  { 0, 0, 0, "tcp_xmit_hiwat"},
    178  { 0, 0, 0, "tcp_xmit_lowat"},
    179  { 0, 0, 0, "tcp_recv_hiwat"},
    180  { 0, 0, 0, "tcp_recv_hiwat_minmss"},
    181  { 0, 0, 0, "tcp_fin_wait_2_flush_interval"},
    182  { 0, 0, 0, "tcp_max_buf"},
    183  { 0, 0, 0, "tcp_strong_iss"},
    184  { 0, 0, 0, "tcp_rtt_updates"},
    185  { 0, 0, 0, "tcp_wscale_always"},
    186  { 0, 0, 0, "tcp_tstamp_always"},
    187  { 0, 0, 0, "tcp_tstamp_if_wscale"},
    188  { 0, 0, 0, "tcp_rexmit_interval_extra"},
    189  { 0, 0, 0, "tcp_deferred_acks_max"},
    190  { 0, 0, 0, "tcp_slow_start_after_idle"},
    191  { 0, 0, 0, "tcp_slow_start_initial"},
    192  { 0, 0, 0, "tcp_sack_permitted"},
    193 #ifdef DEBUG
    194  { 0, 0, 0, "tcp_drop_oob"},
    195 #endif
    196 };
    197 
    198 /*
    199  * Obsolete nca variables, just warn.
    200  */
    201 
    202 ncaparam_t	nca_nca_obsolete_arr[] = {
    203  { 0, 0, 0, "nca_ipport_table_bucket"},
    204  { 0, 0, 0, "nca_ipport_table_size"},
    205  { 0, 0, 0, "nca_ipport_table_expand"},
    206  { 0, 0, 0, "nca_ipport_table_shrink"},
    207  { 0, 0, 0, "nca_ip_virtual_hosting"},
    208  { 0, 0, 0, "httpd_door_address"},
    209  { 0, 0, 0, "httpd_door_path"},
    210  { 0, 0, 0, "httpd_downdoor_path"},
    211  { 0, 0, 0, "nca_ppmax"},
    212  { 0, 0, 0, "nca_vpmax"},
    213  { 0, 0, 0, "nca_use_segmap"},
    214  { 0, 0, 0, "nca_availrmem"},
    215  { 0, 0, 0, "nca_maxkmem"},
    216  { 0, 0, 0, "nca_log_file"},
    217  { 0, 0, 0, "conn_status"},
    218  { 0, 0, 0, "conn_status_all"},
    219  { 0, 0, 0, "nca_conn_req_max_q"},
    220  { 0, 0, 0, "nca_conn_req_max_q0"},
    221  { 0, 0, 0, "cache_clear"},
    222  { 0, 0, 0, "nca_node_hash"},
    223  { 0, 0, 0, "node_status"},
    224 #ifdef DEBUG
    225  { 0, 0, 0, "nca_debug_counter"},
    226 #endif
    227 };
    228 /* END CSTYLED */
    229 
    230 static int
    231 /*ARGSUSED*/
    232 nl7c_uri_ttl_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    233 {
    234 	(void) mi_mpprintf(mp, "%ld", nl7c_uri_ttl);
    235 	return (0);
    236 }
    237 
    238 static int
    239 /*ARGSUSED*/
    240 nl7c_uri_ttl_set(queue_t *q, mblk_t *mp, char *value, caddr_t nu, cred_t *cr)
    241 {
    242 	if (ddi_strtol(value, NULL, 10, &nl7c_uri_ttl) != 0)
    243 		return (EINVAL);
    244 	return (0);
    245 }
    246 
    247 static int
    248 /*ARGSUSED*/
    249 nca_logging_on_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    250 {
    251 	(void) mi_mpprintf(mp, "%d", nl7c_logd_enabled);
    252 	return (0);
    253 }
    254 
    255 static int
    256 /*ARGSUSED*/
    257 nca_logging_on_set(queue_t *q, mblk_t *mp, char *value, caddr_t nu, cred_t *cr)
    258 {
    259 	long new_value;
    260 
    261 	if (ddi_strtol(value, NULL, 10, &new_value) != 0 || new_value < 0 ||
    262 	    new_value > 1) {
    263 		return (EINVAL);
    264 	}
    265 	if (nca_fio_cnt(nl7c_logd_fio) == 0)
    266 		return (EINVAL);
    267 	nl7c_logd_enabled = new_value;
    268 
    269 	return (0);
    270 }
    271 
    272 static int
    273 /*ARGSUSED*/
    274 nca_version_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    275 {
    276 	(void) mi_mpprintf(mp, "%d.%d", nca_major_version, nca_minor_version);
    277 	return (0);
    278 }
    279 
    280 static int
    281 /*ARGSUSED*/
    282 nca_httpd_version_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    283 {
    284 	(void) mi_mpprintf(mp, "%d", nca_httpd_version);
    285 	return (0);
    286 }
    287 
    288 static int
    289 /*ARGSUSED*/
    290 nca_logd_version_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    291 {
    292 	(void) mi_mpprintf(mp, "%d", nca_logd_version);
    293 	return (0);
    294 }
    295 
    296 static int
    297 /*ARGSUSED*/
    298 nca_httpd_door_inst_get(queue_t *q, mblk_t *mp, caddr_t nu, cred_t *cr)
    299 {
    300 	nl7c_mi_report_addr(mp);
    301 	return (0);
    302 }
    303 
    304 static int
    305 /*ARGSUSED*/
    306 nca_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    307 {
    308 	ncaparam_t	*ncapa = (ncaparam_t *)cp;
    309 
    310 	(void) mi_mpprintf(mp, "%ld", ncapa->param_val);
    311 	return (0);
    312 }
    313 
    314 static int
    315 /*ARGSUSED*/
    316 nca_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr)
    317 {
    318 	ulong_t		new_value;
    319 	ncaparam_t	*ncapa = (ncaparam_t *)cp;
    320 
    321 	if (ddi_strtoul(value, NULL, 10, &new_value) != 0 ||
    322 	    new_value < ncapa->param_min || new_value > ncapa->param_max) {
    323 		return (EINVAL);
    324 	}
    325 	ncapa->param_val = new_value;
    326 	return (0);
    327 }
    328 
    329 static int
    330 /*ARGSUSED*/
    331 nca_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    332 {
    333 	(void) mi_mpprintf(mp, "obsolete");
    334 	return (0);
    335 }
    336 
    337 static int
    338 /*ARGSUSED*/
    339 nca_ip_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    340 {
    341 	(void) mi_mpprintf(mp, "obsolete for /dev/nca, use /dev/ip");
    342 	return (0);
    343 }
    344 
    345 static int
    346 /*ARGSUSED*/
    347 nca_tcp_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    348 {
    349 	(void) mi_mpprintf(mp, "obsolete for /dev/nca, use /dev/tcp");
    350 	return (0);
    351 }
    352 
    353 static int
    354 /*ARGSUSED*/
    355 nca_nca_obsolete(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
    356 {
    357 	(void) mi_mpprintf(mp, "obsolete for /dev/nca");
    358 	return (0);
    359 }
    360 
    361 static boolean_t
    362 nca_param_register(ncaparam_t *ncapa, int cnt)
    363 {
    364 	for (; cnt-- > 0; ncapa++) {
    365 		if (ncapa->param_name && ncapa->param_name[0]) {
    366 			if (!nd_load(&nca_g_nd, ncapa->param_name,
    367 			    nca_param_get, nca_param_set,
    368 			    (caddr_t)ncapa)) {
    369 				goto error;
    370 			}
    371 		}
    372 
    373 	}
    374 	if (!nd_load(&nca_g_nd, "nca_version", nca_version_get, nil(pfi_t),
    375 	    nil(caddr_t))) {
    376 		goto error;
    377 	}
    378 	if (!nd_load(&nca_g_nd, "nca_logd_version", nca_logd_version_get,
    379 	    nil(pfi_t), nil(caddr_t))) {
    380 		goto error;
    381 	}
    382 	if (!nd_load(&nca_g_nd, "nca_logging_on", nca_logging_on_get,
    383 	    nca_logging_on_set, nil(caddr_t))) {
    384 		goto error;
    385 	}
    386 
    387 	if (!nd_load(&nca_g_nd, "uri_time_to_live", nl7c_uri_ttl_get,
    388 	    nl7c_uri_ttl_set, nil(caddr_t))) {
    389 		goto error;
    390 	}
    391 	if (!nd_load(&nca_g_nd, "nca_httpd_version", nca_httpd_version_get,
    392 	    nil(pfi_t), nil(caddr_t))) {
    393 		goto error;
    394 	}
    395 	if (!nd_load(&nca_g_nd, "httpd_door_instance", nca_httpd_door_inst_get,
    396 	    nil(pfi_t), nil(caddr_t))) {
    397 		nd_free(&nca_g_nd);
    398 		return (B_FALSE);
    399 	}
    400 
    401 	ncapa = nca_ip_obsolete_arr;
    402 	cnt = A_CNT(nca_ip_obsolete_arr);
    403 	for (; cnt-- > 0; ncapa++) {
    404 		if (ncapa->param_name && ncapa->param_name[0]) {
    405 			if (!nd_load(&nca_g_nd, ncapa->param_name,
    406 			    nca_ip_obsolete, NULL, (caddr_t)ncapa)) {
    407 				goto error;
    408 			}
    409 		}
    410 
    411 	}
    412 
    413 	ncapa = nca_tcp_obsolete_arr;
    414 	cnt = A_CNT(nca_tcp_obsolete_arr);
    415 	for (; cnt-- > 0; ncapa++) {
    416 		if (ncapa->param_name && ncapa->param_name[0]) {
    417 			if (!nd_load(&nca_g_nd, ncapa->param_name,
    418 			    nca_tcp_obsolete, NULL, (caddr_t)ncapa)) {
    419 				goto error;
    420 			}
    421 		}
    422 
    423 	}
    424 
    425 	ncapa = nca_nca_obsolete_arr;
    426 	cnt = A_CNT(nca_nca_obsolete_arr);
    427 	for (; cnt-- > 0; ncapa++) {
    428 		if (ncapa->param_name && ncapa->param_name[0]) {
    429 			if (!nd_load(&nca_g_nd, ncapa->param_name,
    430 			    nca_nca_obsolete, NULL, (caddr_t)ncapa)) {
    431 				goto error;
    432 			}
    433 		}
    434 
    435 	}
    436 
    437 	return (B_TRUE);
    438 
    439 error:
    440 	nd_free(&nca_g_nd);
    441 	return (B_FALSE);
    442 }
    443 
    444 void
    445 nl7c_nca_init(void)
    446 {
    447 	if (! nca_g_nd) {
    448 		if (! nca_param_register(nca_param_arr, A_CNT(nca_param_arr)))
    449 			cmn_err(CE_WARN,
    450 			    "nl7c: /dev/nca ndd initialization failed.");
    451 	}
    452 }
    453