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