162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#include <linux/mm.h>
762306a36Sopenharmony_ci#include <linux/slab.h>
862306a36Sopenharmony_ci#include <linux/sysctl.h>
962306a36Sopenharmony_ci#include <linux/spinlock.h>
1062306a36Sopenharmony_ci#include <net/ax25.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistatic int min_ipdefmode[1],    	max_ipdefmode[] = {1};
1362306a36Sopenharmony_cistatic int min_axdefmode[1],            max_axdefmode[] = {1};
1462306a36Sopenharmony_cistatic int min_backoff[1],		max_backoff[] = {2};
1562306a36Sopenharmony_cistatic int min_conmode[1],		max_conmode[] = {2};
1662306a36Sopenharmony_cistatic int min_window[] = {1},		max_window[] = {7};
1762306a36Sopenharmony_cistatic int min_ewindow[] = {1},		max_ewindow[] = {63};
1862306a36Sopenharmony_cistatic int min_t1[] = {1},		max_t1[] = {30000};
1962306a36Sopenharmony_cistatic int min_t2[] = {1},		max_t2[] = {20000};
2062306a36Sopenharmony_cistatic int min_t3[1],			max_t3[] = {3600000};
2162306a36Sopenharmony_cistatic int min_idle[1],			max_idle[] = {65535000};
2262306a36Sopenharmony_cistatic int min_n2[] = {1},		max_n2[] = {31};
2362306a36Sopenharmony_cistatic int min_paclen[] = {1},		max_paclen[] = {512};
2462306a36Sopenharmony_cistatic int min_proto[1],		max_proto[] = { AX25_PROTO_MAX };
2562306a36Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
2662306a36Sopenharmony_cistatic int min_ds_timeout[1],		max_ds_timeout[] = {65535000};
2762306a36Sopenharmony_ci#endif
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic const struct ctl_table ax25_param_table[] = {
3062306a36Sopenharmony_ci	{
3162306a36Sopenharmony_ci		.procname	= "ip_default_mode",
3262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
3362306a36Sopenharmony_ci		.mode		= 0644,
3462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
3562306a36Sopenharmony_ci		.extra1		= &min_ipdefmode,
3662306a36Sopenharmony_ci		.extra2		= &max_ipdefmode
3762306a36Sopenharmony_ci	},
3862306a36Sopenharmony_ci	{
3962306a36Sopenharmony_ci		.procname	= "ax25_default_mode",
4062306a36Sopenharmony_ci		.maxlen		= sizeof(int),
4162306a36Sopenharmony_ci		.mode		= 0644,
4262306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
4362306a36Sopenharmony_ci		.extra1		= &min_axdefmode,
4462306a36Sopenharmony_ci		.extra2		= &max_axdefmode
4562306a36Sopenharmony_ci	},
4662306a36Sopenharmony_ci	{
4762306a36Sopenharmony_ci		.procname	= "backoff_type",
4862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
4962306a36Sopenharmony_ci		.mode		= 0644,
5062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
5162306a36Sopenharmony_ci		.extra1		= &min_backoff,
5262306a36Sopenharmony_ci		.extra2		= &max_backoff
5362306a36Sopenharmony_ci	},
5462306a36Sopenharmony_ci	{
5562306a36Sopenharmony_ci		.procname	= "connect_mode",
5662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
5762306a36Sopenharmony_ci		.mode		= 0644,
5862306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
5962306a36Sopenharmony_ci		.extra1		= &min_conmode,
6062306a36Sopenharmony_ci		.extra2		= &max_conmode
6162306a36Sopenharmony_ci	},
6262306a36Sopenharmony_ci	{
6362306a36Sopenharmony_ci		.procname	= "standard_window_size",
6462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
6562306a36Sopenharmony_ci		.mode		= 0644,
6662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
6762306a36Sopenharmony_ci		.extra1		= &min_window,
6862306a36Sopenharmony_ci		.extra2		= &max_window
6962306a36Sopenharmony_ci	},
7062306a36Sopenharmony_ci	{
7162306a36Sopenharmony_ci		.procname	= "extended_window_size",
7262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
7362306a36Sopenharmony_ci		.mode		= 0644,
7462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
7562306a36Sopenharmony_ci		.extra1		= &min_ewindow,
7662306a36Sopenharmony_ci		.extra2		= &max_ewindow
7762306a36Sopenharmony_ci	},
7862306a36Sopenharmony_ci	{
7962306a36Sopenharmony_ci		.procname	= "t1_timeout",
8062306a36Sopenharmony_ci		.maxlen		= sizeof(int),
8162306a36Sopenharmony_ci		.mode		= 0644,
8262306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
8362306a36Sopenharmony_ci		.extra1		= &min_t1,
8462306a36Sopenharmony_ci		.extra2		= &max_t1
8562306a36Sopenharmony_ci	},
8662306a36Sopenharmony_ci	{
8762306a36Sopenharmony_ci		.procname	= "t2_timeout",
8862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
8962306a36Sopenharmony_ci		.mode		= 0644,
9062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
9162306a36Sopenharmony_ci		.extra1		= &min_t2,
9262306a36Sopenharmony_ci		.extra2		= &max_t2
9362306a36Sopenharmony_ci	},
9462306a36Sopenharmony_ci	{
9562306a36Sopenharmony_ci		.procname	= "t3_timeout",
9662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
9762306a36Sopenharmony_ci		.mode		= 0644,
9862306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
9962306a36Sopenharmony_ci		.extra1		= &min_t3,
10062306a36Sopenharmony_ci		.extra2		= &max_t3
10162306a36Sopenharmony_ci	},
10262306a36Sopenharmony_ci	{
10362306a36Sopenharmony_ci		.procname	= "idle_timeout",
10462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
10562306a36Sopenharmony_ci		.mode		= 0644,
10662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
10762306a36Sopenharmony_ci		.extra1		= &min_idle,
10862306a36Sopenharmony_ci		.extra2		= &max_idle
10962306a36Sopenharmony_ci	},
11062306a36Sopenharmony_ci	{
11162306a36Sopenharmony_ci		.procname	= "maximum_retry_count",
11262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
11362306a36Sopenharmony_ci		.mode		= 0644,
11462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
11562306a36Sopenharmony_ci		.extra1		= &min_n2,
11662306a36Sopenharmony_ci		.extra2		= &max_n2
11762306a36Sopenharmony_ci	},
11862306a36Sopenharmony_ci	{
11962306a36Sopenharmony_ci		.procname	= "maximum_packet_length",
12062306a36Sopenharmony_ci		.maxlen		= sizeof(int),
12162306a36Sopenharmony_ci		.mode		= 0644,
12262306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
12362306a36Sopenharmony_ci		.extra1		= &min_paclen,
12462306a36Sopenharmony_ci		.extra2		= &max_paclen
12562306a36Sopenharmony_ci	},
12662306a36Sopenharmony_ci	{
12762306a36Sopenharmony_ci		.procname	= "protocol",
12862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
12962306a36Sopenharmony_ci		.mode		= 0644,
13062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
13162306a36Sopenharmony_ci		.extra1		= &min_proto,
13262306a36Sopenharmony_ci		.extra2		= &max_proto
13362306a36Sopenharmony_ci	},
13462306a36Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
13562306a36Sopenharmony_ci	{
13662306a36Sopenharmony_ci		.procname	= "dama_slave_timeout",
13762306a36Sopenharmony_ci		.maxlen		= sizeof(int),
13862306a36Sopenharmony_ci		.mode		= 0644,
13962306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
14062306a36Sopenharmony_ci		.extra1		= &min_ds_timeout,
14162306a36Sopenharmony_ci		.extra2		= &max_ds_timeout
14262306a36Sopenharmony_ci	},
14362306a36Sopenharmony_ci#endif
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	{ }	/* that's all, folks! */
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ciint ax25_register_dev_sysctl(ax25_dev *ax25_dev)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	char path[sizeof("net/ax25/") + IFNAMSIZ];
15162306a36Sopenharmony_ci	int k;
15262306a36Sopenharmony_ci	struct ctl_table *table;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL);
15562306a36Sopenharmony_ci	if (!table)
15662306a36Sopenharmony_ci		return -ENOMEM;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	for (k = 0; k < AX25_MAX_VALUES; k++)
15962306a36Sopenharmony_ci		table[k].data = &ax25_dev->values[k];
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	snprintf(path, sizeof(path), "net/ax25/%s", ax25_dev->dev->name);
16262306a36Sopenharmony_ci	ax25_dev->sysheader = register_net_sysctl_sz(&init_net, path, table,
16362306a36Sopenharmony_ci						     ARRAY_SIZE(ax25_param_table));
16462306a36Sopenharmony_ci	if (!ax25_dev->sysheader) {
16562306a36Sopenharmony_ci		kfree(table);
16662306a36Sopenharmony_ci		return -ENOMEM;
16762306a36Sopenharmony_ci	}
16862306a36Sopenharmony_ci	return 0;
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_civoid ax25_unregister_dev_sysctl(ax25_dev *ax25_dev)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	struct ctl_table_header *header = ax25_dev->sysheader;
17462306a36Sopenharmony_ci	struct ctl_table *table;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	if (header) {
17762306a36Sopenharmony_ci		ax25_dev->sysheader = NULL;
17862306a36Sopenharmony_ci		table = header->ctl_table_arg;
17962306a36Sopenharmony_ci		unregister_net_sysctl_table(header);
18062306a36Sopenharmony_ci		kfree(table);
18162306a36Sopenharmony_ci	}
18262306a36Sopenharmony_ci}
183