linux-stable/drivers/staging/ipx/ipx_proc.c
Linus Torvalds 5d8515bc23 Staging/IIO patches for 4.16-rc1
Here is the big Staging and IIO driver patches for 4.16-rc1.
 
 There is the normal amount of new IIO drivers added, like all releases.
 
 The networking IPX and the ncpfs filesystem are moved into the staging
 tree, as they are on their way out of the kernel due to lack of use
 anymore.
 
 The visorbus subsystem finall has started moving out of the staging tree
 to the "real" part of the kernel, and the most and fsl-mc codebases are
 almost ready to move out, that will probably happen for 4.17-rc1 if all
 goes well.
 
 Other than that, there is a bunch of license header cleanups in the
 tree, along with the normal amount of coding style churn that we all
 know and love for this codebase.  I also got frustrated at the
 Meltdown/Spectre mess and took it out on the dgnc tty driver, deleting
 huge chunks of it that were never even being used.
 
 Full details of everything is in the shortlog.
 
 All of these patches have been in linux-next for a while with no
 reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWnLxoA8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yk4vgCgjeMlwhtar65DIticIRj626EFxiQAnjGmH8Kd
 d9Xz2Piq8X47uSsC/6AE
 =xxMT
 -----END PGP SIGNATURE-----

Merge tag 'staging-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging/IIO updates from Greg KH:
 "Here is the big Staging and IIO driver patches for 4.16-rc1.

  There is the normal amount of new IIO drivers added, like all
  releases.

  The networking IPX and the ncpfs filesystem are moved into the staging
  tree, as they are on their way out of the kernel due to lack of use
  anymore.

  The visorbus subsystem finall has started moving out of the staging
  tree to the "real" part of the kernel, and the most and fsl-mc
  codebases are almost ready to move out, that will probably happen for
  4.17-rc1 if all goes well.

  Other than that, there is a bunch of license header cleanups in the
  tree, along with the normal amount of coding style churn that we all
  know and love for this codebase. I also got frustrated at the
  Meltdown/Spectre mess and took it out on the dgnc tty driver, deleting
  huge chunks of it that were never even being used.

  Full details of everything is in the shortlog.

  All of these patches have been in linux-next for a while with no
  reported issues"

* tag 'staging-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (627 commits)
  staging: rtlwifi: remove redundant initialization of 'cfg_cmd'
  staging: rtl8723bs: remove a couple of redundant initializations
  staging: comedi: reformat lines to 80 chars or less
  staging: lustre: separate a connection destroy from free struct kib_conn
  Staging: rtl8723bs: Use !x instead of NULL comparison
  Staging: rtl8723bs: Remove dead code
  Staging: rtl8723bs: Change names to conform to the kernel code
  staging: ccree: Fix missing blank line after declaration
  staging: rtl8188eu: remove redundant initialization of 'pwrcfgcmd'
  staging: rtlwifi: remove unused RTLHALMAC_ST and RTLPHYDM_ST
  staging: fbtft: remove unused FB_TFT_SSD1325 kconfig
  staging: comedi: dt2811: remove redundant initialization of 'ns'
  staging: wilc1000: fix alignments to match open parenthesis
  staging: wilc1000: removed unnecessary defined enums typedef
  staging: wilc1000: remove unnecessary use of parentheses
  staging: rtl8192u: remove redundant initialization of 'timeout'
  staging: sm750fb: fix CamelCase for dispSet var
  staging: lustre: lnet/selftest: fix compile error on UP build
  staging: rtl8723bs: hal_com_phycfg: Remove unneeded semicolons
  staging: rts5208: Fix "seg_no" calculation in reset_ms_card()
  ...
2018-02-01 09:51:57 -08:00

338 lines
7.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* IPX proc routines
*
* Copyright(C) Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2002
*/
#include <linux/init.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/seq_file.h>
#include <linux/export.h>
#include <net/net_namespace.h>
#include <net/tcp_states.h>
#include <net/ipx.h>
static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
{
spin_lock_bh(&ipx_interfaces_lock);
return seq_list_start_head(&ipx_interfaces, *pos);
}
static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
{
return seq_list_next(v, &ipx_interfaces, pos);
}
static void ipx_seq_interface_stop(struct seq_file *seq, void *v)
{
spin_unlock_bh(&ipx_interfaces_lock);
}
static int ipx_seq_interface_show(struct seq_file *seq, void *v)
{
struct ipx_interface *i;
if (v == &ipx_interfaces) {
seq_puts(seq, "Network Node_Address Primary Device "
"Frame_Type");
#ifdef IPX_REFCNT_DEBUG
seq_puts(seq, " refcnt");
#endif
seq_puts(seq, "\n");
goto out;
}
i = list_entry(v, struct ipx_interface, node);
seq_printf(seq, "%08X ", ntohl(i->if_netnum));
seq_printf(seq, "%02X%02X%02X%02X%02X%02X ",
i->if_node[0], i->if_node[1], i->if_node[2],
i->if_node[3], i->if_node[4], i->if_node[5]);
seq_printf(seq, "%-9s", i == ipx_primary_net ? "Yes" : "No");
seq_printf(seq, "%-11s", ipx_device_name(i));
seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type));
#ifdef IPX_REFCNT_DEBUG
seq_printf(seq, "%6d", refcount_read(&i->refcnt));
#endif
seq_puts(seq, "\n");
out:
return 0;
}
static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos)
{
read_lock_bh(&ipx_routes_lock);
return seq_list_start_head(&ipx_routes, *pos);
}
static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
{
return seq_list_next(v, &ipx_routes, pos);
}
static void ipx_seq_route_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&ipx_routes_lock);
}
static int ipx_seq_route_show(struct seq_file *seq, void *v)
{
struct ipx_route *rt;
if (v == &ipx_routes) {
seq_puts(seq, "Network Router_Net Router_Node\n");
goto out;
}
rt = list_entry(v, struct ipx_route, node);
seq_printf(seq, "%08X ", ntohl(rt->ir_net));
if (rt->ir_routed)
seq_printf(seq, "%08X %02X%02X%02X%02X%02X%02X\n",
ntohl(rt->ir_intrfc->if_netnum),
rt->ir_router_node[0], rt->ir_router_node[1],
rt->ir_router_node[2], rt->ir_router_node[3],
rt->ir_router_node[4], rt->ir_router_node[5]);
else
seq_puts(seq, "Directly Connected\n");
out:
return 0;
}
static __inline__ struct sock *ipx_get_socket_idx(loff_t pos)
{
struct sock *s = NULL;
struct ipx_interface *i;
list_for_each_entry(i, &ipx_interfaces, node) {
spin_lock_bh(&i->if_sklist_lock);
sk_for_each(s, &i->if_sklist) {
if (!pos)
break;
--pos;
}
spin_unlock_bh(&i->if_sklist_lock);
if (!pos) {
if (s)
goto found;
break;
}
}
s = NULL;
found:
return s;
}
static void *ipx_seq_socket_start(struct seq_file *seq, loff_t *pos)
{
loff_t l = *pos;
spin_lock_bh(&ipx_interfaces_lock);
return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN;
}
static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock* sk, *next;
struct ipx_interface *i;
struct ipx_sock *ipxs;
++*pos;
if (v == SEQ_START_TOKEN) {
sk = NULL;
i = ipx_interfaces_head();
if (!i)
goto out;
sk = sk_head(&i->if_sklist);
if (sk)
spin_lock_bh(&i->if_sklist_lock);
goto out;
}
sk = v;
next = sk_next(sk);
if (next) {
sk = next;
goto out;
}
ipxs = ipx_sk(sk);
i = ipxs->intrfc;
spin_unlock_bh(&i->if_sklist_lock);
sk = NULL;
for (;;) {
if (i->node.next == &ipx_interfaces)
break;
i = list_entry(i->node.next, struct ipx_interface, node);
spin_lock_bh(&i->if_sklist_lock);
if (!hlist_empty(&i->if_sklist)) {
sk = sk_head(&i->if_sklist);
break;
}
spin_unlock_bh(&i->if_sklist_lock);
}
out:
return sk;
}
static int ipx_seq_socket_show(struct seq_file *seq, void *v)
{
struct sock *s;
struct ipx_sock *ipxs;
if (v == SEQ_START_TOKEN) {
#ifdef CONFIG_IPX_INTERN
seq_puts(seq, "Local_Address "
"Remote_Address Tx_Queue "
"Rx_Queue State Uid\n");
#else
seq_puts(seq, "Local_Address Remote_Address "
"Tx_Queue Rx_Queue State Uid\n");
#endif
goto out;
}
s = v;
ipxs = ipx_sk(s);
#ifdef CONFIG_IPX_INTERN
seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ",
ntohl(ipxs->intrfc->if_netnum),
ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3],
ipxs->node[4], ipxs->node[5], ntohs(ipxs->port));
#else
seq_printf(seq, "%08X:%04X ", ntohl(ipxs->intrfc->if_netnum),
ntohs(ipxs->port));
#endif /* CONFIG_IPX_INTERN */
if (s->sk_state != TCP_ESTABLISHED)
seq_printf(seq, "%-28s", "Not_Connected");
else {
seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ",
ntohl(ipxs->dest_addr.net),
ipxs->dest_addr.node[0], ipxs->dest_addr.node[1],
ipxs->dest_addr.node[2], ipxs->dest_addr.node[3],
ipxs->dest_addr.node[4], ipxs->dest_addr.node[5],
ntohs(ipxs->dest_addr.sock));
}
seq_printf(seq, "%08X %08X %02X %03u\n",
sk_wmem_alloc_get(s),
sk_rmem_alloc_get(s),
s->sk_state,
from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)));
out:
return 0;
}
static const struct seq_operations ipx_seq_interface_ops = {
.start = ipx_seq_interface_start,
.next = ipx_seq_interface_next,
.stop = ipx_seq_interface_stop,
.show = ipx_seq_interface_show,
};
static const struct seq_operations ipx_seq_route_ops = {
.start = ipx_seq_route_start,
.next = ipx_seq_route_next,
.stop = ipx_seq_route_stop,
.show = ipx_seq_route_show,
};
static const struct seq_operations ipx_seq_socket_ops = {
.start = ipx_seq_socket_start,
.next = ipx_seq_socket_next,
.stop = ipx_seq_interface_stop,
.show = ipx_seq_socket_show,
};
static int ipx_seq_route_open(struct inode *inode, struct file *file)
{
return seq_open(file, &ipx_seq_route_ops);
}
static int ipx_seq_interface_open(struct inode *inode, struct file *file)
{
return seq_open(file, &ipx_seq_interface_ops);
}
static int ipx_seq_socket_open(struct inode *inode, struct file *file)
{
return seq_open(file, &ipx_seq_socket_ops);
}
static const struct file_operations ipx_seq_interface_fops = {
.open = ipx_seq_interface_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static const struct file_operations ipx_seq_route_fops = {
.open = ipx_seq_route_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static const struct file_operations ipx_seq_socket_fops = {
.open = ipx_seq_socket_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct proc_dir_entry *ipx_proc_dir;
int __init ipx_proc_init(void)
{
struct proc_dir_entry *p;
int rc = -ENOMEM;
ipx_proc_dir = proc_mkdir("ipx", init_net.proc_net);
if (!ipx_proc_dir)
goto out;
p = proc_create("interface", S_IRUGO,
ipx_proc_dir, &ipx_seq_interface_fops);
if (!p)
goto out_interface;
p = proc_create("route", S_IRUGO, ipx_proc_dir, &ipx_seq_route_fops);
if (!p)
goto out_route;
p = proc_create("socket", S_IRUGO, ipx_proc_dir, &ipx_seq_socket_fops);
if (!p)
goto out_socket;
rc = 0;
out:
return rc;
out_socket:
remove_proc_entry("route", ipx_proc_dir);
out_route:
remove_proc_entry("interface", ipx_proc_dir);
out_interface:
remove_proc_entry("ipx", init_net.proc_net);
goto out;
}
void __exit ipx_proc_exit(void)
{
remove_proc_entry("interface", ipx_proc_dir);
remove_proc_entry("route", ipx_proc_dir);
remove_proc_entry("socket", ipx_proc_dir);
remove_proc_entry("ipx", init_net.proc_net);
}
#else /* CONFIG_PROC_FS */
int __init ipx_proc_init(void)
{
return 0;
}
void __exit ipx_proc_exit(void)
{
}
#endif /* CONFIG_PROC_FS */