cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sysctl_net_decnet.c (7247B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * DECnet       An implementation of the DECnet protocol suite for the LINUX
      4 *              operating system.  DECnet is implemented using the  BSD Socket
      5 *              interface as the means of communication with the user level.
      6 *
      7 *              DECnet sysctl support functions
      8 *
      9 * Author:      Steve Whitehouse <SteveW@ACM.org>
     10 *
     11 *
     12 * Changes:
     13 * Steve Whitehouse - C99 changes and default device handling
     14 * Steve Whitehouse - Memory buffer settings, like the tcp ones
     15 *
     16 */
     17#include <linux/mm.h>
     18#include <linux/sysctl.h>
     19#include <linux/fs.h>
     20#include <linux/netdevice.h>
     21#include <linux/string.h>
     22#include <net/neighbour.h>
     23#include <net/dst.h>
     24#include <net/flow.h>
     25
     26#include <linux/uaccess.h>
     27
     28#include <net/dn.h>
     29#include <net/dn_dev.h>
     30#include <net/dn_route.h>
     31
     32
     33int decnet_debug_level;
     34int decnet_time_wait = 30;
     35int decnet_dn_count = 1;
     36int decnet_di_count = 3;
     37int decnet_dr_count = 3;
     38int decnet_log_martians = 1;
     39int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
     40
     41/* Reasonable defaults, I hope, based on tcp's defaults */
     42long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
     43int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
     44int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
     45
     46#ifdef CONFIG_SYSCTL
     47extern int decnet_dst_gc_interval;
     48static int min_decnet_time_wait[] = { 5 };
     49static int max_decnet_time_wait[] = { 600 };
     50static int min_state_count[] = { 1 };
     51static int max_state_count[] = { NSP_MAXRXTSHIFT };
     52static int min_decnet_dst_gc_interval[] = { 1 };
     53static int max_decnet_dst_gc_interval[] = { 60 };
     54static int min_decnet_no_fc_max_cwnd[] = { NSP_MIN_WINDOW };
     55static int max_decnet_no_fc_max_cwnd[] = { NSP_MAX_WINDOW };
     56static char node_name[7] = "???";
     57
     58static struct ctl_table_header *dn_table_header = NULL;
     59
     60/*
     61 * ctype.h :-)
     62 */
     63#define ISNUM(x) (((x) >= '0') && ((x) <= '9'))
     64#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z'))
     65#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z'))
     66#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
     67#define INVALID_END_CHAR(x) (ISNUM(x) || ISALPHA(x))
     68
     69static void strip_it(char *str)
     70{
     71	for(;;) {
     72		switch (*str) {
     73		case ' ':
     74		case '\n':
     75		case '\r':
     76		case ':':
     77			*str = 0;
     78			fallthrough;
     79		case 0:
     80			return;
     81		}
     82		str++;
     83	}
     84}
     85
     86/*
     87 * Simple routine to parse an ascii DECnet address
     88 * into a network order address.
     89 */
     90static int parse_addr(__le16 *addr, char *str)
     91{
     92	__u16 area, node;
     93
     94	while(*str && !ISNUM(*str)) str++;
     95
     96	if (*str == 0)
     97		return -1;
     98
     99	area = (*str++ - '0');
    100	if (ISNUM(*str)) {
    101		area *= 10;
    102		area += (*str++ - '0');
    103	}
    104
    105	if (*str++ != '.')
    106		return -1;
    107
    108	if (!ISNUM(*str))
    109		return -1;
    110
    111	node = *str++ - '0';
    112	if (ISNUM(*str)) {
    113		node *= 10;
    114		node += (*str++ - '0');
    115	}
    116	if (ISNUM(*str)) {
    117		node *= 10;
    118		node += (*str++ - '0');
    119	}
    120	if (ISNUM(*str)) {
    121		node *= 10;
    122		node += (*str++ - '0');
    123	}
    124
    125	if ((node > 1023) || (area > 63))
    126		return -1;
    127
    128	if (INVALID_END_CHAR(*str))
    129		return -1;
    130
    131	*addr = cpu_to_le16((area << 10) | node);
    132
    133	return 0;
    134}
    135
    136static int dn_node_address_handler(struct ctl_table *table, int write,
    137		void *buffer, size_t *lenp, loff_t *ppos)
    138{
    139	char addr[DN_ASCBUF_LEN];
    140	size_t len;
    141	__le16 dnaddr;
    142
    143	if (!*lenp || (*ppos && !write)) {
    144		*lenp = 0;
    145		return 0;
    146	}
    147
    148	if (write) {
    149		len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1);
    150		memcpy(addr, buffer, len);
    151		addr[len] = 0;
    152		strip_it(addr);
    153
    154		if (parse_addr(&dnaddr, addr))
    155			return -EINVAL;
    156
    157		dn_dev_devices_off();
    158
    159		decnet_address = dnaddr;
    160
    161		dn_dev_devices_on();
    162
    163		*ppos += len;
    164
    165		return 0;
    166	}
    167
    168	dn_addr2asc(le16_to_cpu(decnet_address), addr);
    169	len = strlen(addr);
    170	addr[len++] = '\n';
    171
    172	if (len > *lenp)
    173		len = *lenp;
    174	memcpy(buffer, addr, len);
    175	*lenp = len;
    176	*ppos += len;
    177
    178	return 0;
    179}
    180
    181static int dn_def_dev_handler(struct ctl_table *table, int write,
    182		void *buffer, size_t *lenp, loff_t *ppos)
    183{
    184	size_t len;
    185	struct net_device *dev;
    186	char devname[17];
    187
    188	if (!*lenp || (*ppos && !write)) {
    189		*lenp = 0;
    190		return 0;
    191	}
    192
    193	if (write) {
    194		if (*lenp > 16)
    195			return -E2BIG;
    196
    197		memcpy(devname, buffer, *lenp);
    198		devname[*lenp] = 0;
    199		strip_it(devname);
    200
    201		dev = dev_get_by_name(&init_net, devname);
    202		if (dev == NULL)
    203			return -ENODEV;
    204
    205		if (dev->dn_ptr == NULL) {
    206			dev_put(dev);
    207			return -ENODEV;
    208		}
    209
    210		if (dn_dev_set_default(dev, 1)) {
    211			dev_put(dev);
    212			return -ENODEV;
    213		}
    214		*ppos += *lenp;
    215
    216		return 0;
    217	}
    218
    219	dev = dn_dev_get_default();
    220	if (dev == NULL) {
    221		*lenp = 0;
    222		return 0;
    223	}
    224
    225	strcpy(devname, dev->name);
    226	dev_put(dev);
    227	len = strlen(devname);
    228	devname[len++] = '\n';
    229
    230	if (len > *lenp) len = *lenp;
    231
    232	memcpy(buffer, devname, len);
    233	*lenp = len;
    234	*ppos += len;
    235
    236	return 0;
    237}
    238
    239static struct ctl_table dn_table[] = {
    240	{
    241		.procname = "node_address",
    242		.maxlen = 7,
    243		.mode = 0644,
    244		.proc_handler = dn_node_address_handler,
    245	},
    246	{
    247		.procname = "node_name",
    248		.data = node_name,
    249		.maxlen = 7,
    250		.mode = 0644,
    251		.proc_handler = proc_dostring,
    252	},
    253	{
    254		.procname = "default_device",
    255		.maxlen = 16,
    256		.mode = 0644,
    257		.proc_handler = dn_def_dev_handler,
    258	},
    259	{
    260		.procname = "time_wait",
    261		.data = &decnet_time_wait,
    262		.maxlen = sizeof(int),
    263		.mode = 0644,
    264		.proc_handler = proc_dointvec_minmax,
    265		.extra1 = &min_decnet_time_wait,
    266		.extra2 = &max_decnet_time_wait
    267	},
    268	{
    269		.procname = "dn_count",
    270		.data = &decnet_dn_count,
    271		.maxlen = sizeof(int),
    272		.mode = 0644,
    273		.proc_handler = proc_dointvec_minmax,
    274		.extra1 = &min_state_count,
    275		.extra2 = &max_state_count
    276	},
    277	{
    278		.procname = "di_count",
    279		.data = &decnet_di_count,
    280		.maxlen = sizeof(int),
    281		.mode = 0644,
    282		.proc_handler = proc_dointvec_minmax,
    283		.extra1 = &min_state_count,
    284		.extra2 = &max_state_count
    285	},
    286	{
    287		.procname = "dr_count",
    288		.data = &decnet_dr_count,
    289		.maxlen = sizeof(int),
    290		.mode = 0644,
    291		.proc_handler = proc_dointvec_minmax,
    292		.extra1 = &min_state_count,
    293		.extra2 = &max_state_count
    294	},
    295	{
    296		.procname = "dst_gc_interval",
    297		.data = &decnet_dst_gc_interval,
    298		.maxlen = sizeof(int),
    299		.mode = 0644,
    300		.proc_handler = proc_dointvec_minmax,
    301		.extra1 = &min_decnet_dst_gc_interval,
    302		.extra2 = &max_decnet_dst_gc_interval
    303	},
    304	{
    305		.procname = "no_fc_max_cwnd",
    306		.data = &decnet_no_fc_max_cwnd,
    307		.maxlen = sizeof(int),
    308		.mode = 0644,
    309		.proc_handler = proc_dointvec_minmax,
    310		.extra1 = &min_decnet_no_fc_max_cwnd,
    311		.extra2 = &max_decnet_no_fc_max_cwnd
    312	},
    313       {
    314		.procname = "decnet_mem",
    315		.data = &sysctl_decnet_mem,
    316		.maxlen = sizeof(sysctl_decnet_mem),
    317		.mode = 0644,
    318		.proc_handler = proc_doulongvec_minmax
    319	},
    320	{
    321		.procname = "decnet_rmem",
    322		.data = &sysctl_decnet_rmem,
    323		.maxlen = sizeof(sysctl_decnet_rmem),
    324		.mode = 0644,
    325		.proc_handler = proc_dointvec,
    326	},
    327	{
    328		.procname = "decnet_wmem",
    329		.data = &sysctl_decnet_wmem,
    330		.maxlen = sizeof(sysctl_decnet_wmem),
    331		.mode = 0644,
    332		.proc_handler = proc_dointvec,
    333	},
    334	{
    335		.procname = "debug",
    336		.data = &decnet_debug_level,
    337		.maxlen = sizeof(int),
    338		.mode = 0644,
    339		.proc_handler = proc_dointvec,
    340	},
    341	{ }
    342};
    343
    344void dn_register_sysctl(void)
    345{
    346	dn_table_header = register_net_sysctl(&init_net, "net/decnet", dn_table);
    347}
    348
    349void dn_unregister_sysctl(void)
    350{
    351	unregister_net_sysctl_table(dn_table_header);
    352}
    353
    354#else  /* CONFIG_SYSCTL */
    355void dn_unregister_sysctl(void)
    356{
    357}
    358void dn_register_sysctl(void)
    359{
    360}
    361
    362#endif