// SPDX-License-Identifier: GPL-2.0
/*
 * proc_llc.c - proc interface for LLC
 *
 * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
 *		 2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <linux/seq_file.h>
#include <linux/export.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/llc.h>
#include <net/llc_c_ac.h>
#include <net/llc_c_ev.h>
#include <net/llc_c_st.h>
#include <net/llc_conn.h>

static void llc_ui_format_mac(struct seq_file *seq, const u8 *addr)
{
	seq_printf(seq, "%pM", addr);
}

static struct sock *llc_get_sk_idx(loff_t pos)
{
	struct llc_sap *sap;
	struct sock *sk = NULL;
	int i;

	list_for_each_entry_rcu(sap, &llc_sap_list, node) {
		spin_lock_bh(&sap->sk_lock);
		for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) {
			struct hlist_nulls_head *head = &sap->sk_laddr_hash[i];
			struct hlist_nulls_node *node;

			sk_nulls_for_each(sk, node, head) {
				if (!pos)
					goto found; /* keep the lock */
				--pos;
			}
		}
		spin_unlock_bh(&sap->sk_lock);
	}
	sk = NULL;
found:
	return sk;
}

static void *llc_seq_start(struct seq_file *seq, loff_t *pos) __acquires(RCU)
{
	loff_t l = *pos;

	rcu_read_lock_bh();
	return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
}

static struct sock *laddr_hash_next(struct llc_sap *sap, int bucket)
{
	struct hlist_nulls_node *node;
	struct sock *sk = NULL;

	while (++bucket < LLC_SK_LADDR_HASH_ENTRIES)
		sk_nulls_for_each(sk, node, &sap->sk_laddr_hash[bucket])
			goto out;

out:
	return sk;
}

static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct sock* sk, *next;
	struct llc_sock *llc;
	struct llc_sap *sap;

	++*pos;
	if (v == SEQ_START_TOKEN) {
		sk = llc_get_sk_idx(0);
		goto out;
	}
	sk = v;
	next = sk_nulls_next(sk);
	if (next) {
		sk = next;
		goto out;
	}
	llc = llc_sk(sk);
	sap = llc->sap;
	sk = laddr_hash_next(sap, llc_sk_laddr_hashfn(sap, &llc->laddr));
	if (sk)
		goto out;
	spin_unlock_bh(&sap->sk_lock);
	list_for_each_entry_continue_rcu(sap, &llc_sap_list, node) {
		spin_lock_bh(&sap->sk_lock);
		sk = laddr_hash_next(sap, -1);
		if (sk)
			break; /* keep the lock */
		spin_unlock_bh(&sap->sk_lock);
	}
out:
	return sk;
}

static void llc_seq_stop(struct seq_file *seq, void *v)
{
	if (v && v != SEQ_START_TOKEN) {
		struct sock *sk = v;
		struct llc_sock *llc = llc_sk(sk);
		struct llc_sap *sap = llc->sap;

		spin_unlock_bh(&sap->sk_lock);
	}
	rcu_read_unlock_bh();
}

static int llc_seq_socket_show(struct seq_file *seq, void *v)
{
	struct sock* sk;
	struct llc_sock *llc;

	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "SKt Mc local_mac_sap        remote_mac_sap   "
			      "    tx_queue rx_queue st uid link\n");
		goto out;
	}
	sk = v;
	llc = llc_sk(sk);

	/* FIXME: check if the address is multicast */
	seq_printf(seq, "%2X  %2X ", sk->sk_type, 0);

	if (llc->dev)
		llc_ui_format_mac(seq, llc->dev->dev_addr);
	else {
		u8 addr[6] = {0,0,0,0,0,0};
		llc_ui_format_mac(seq, addr);
	}
	seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
	llc_ui_format_mac(seq, llc->daddr.mac);
	seq_printf(seq, "@%02X %8d %8d %2d %3u %4d\n", llc->daddr.lsap,
		   sk_wmem_alloc_get(sk),
		   sk_rmem_alloc_get(sk) - llc->copied_seq,
		   sk->sk_state,
		   from_kuid_munged(seq_user_ns(seq), sk_uid(sk)),
		   llc->link);
out:
	return 0;
}

static const char *const llc_conn_state_names[] = {
	[LLC_CONN_STATE_ADM] =        "adm",
	[LLC_CONN_STATE_SETUP] =      "setup",
	[LLC_CONN_STATE_NORMAL] =     "normal",
	[LLC_CONN_STATE_BUSY] =       "busy",
	[LLC_CONN_STATE_REJ] =        "rej",
	[LLC_CONN_STATE_AWAIT] =      "await",
	[LLC_CONN_STATE_AWAIT_BUSY] = "await_busy",
	[LLC_CONN_STATE_AWAIT_REJ] =  "await_rej",
	[LLC_CONN_STATE_D_CONN]	=     "d_conn",
	[LLC_CONN_STATE_RESET] =      "reset",
	[LLC_CONN_STATE_ERROR] =      "error",
	[LLC_CONN_STATE_TEMP] =       "temp",
};

static int llc_seq_core_show(struct seq_file *seq, void *v)
{
	struct sock* sk;
	struct llc_sock *llc;

	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "Connection list:\n"
			      "dsap state      retr txw rxw pf ff sf df rs cs "
			      "tack tpfc trs tbs blog busr\n");
		goto out;
	}
	sk = v;
	llc = llc_sk(sk);

	seq_printf(seq, " %02X  %-10s %3d  %3d %3d %2d %2d %2d %2d %2d %2d "
			"%4d %4d %3d %3d %4d %4d\n",
		   llc->daddr.lsap, llc_conn_state_names[llc->state],
		   llc->retry_count, llc->k, llc->rw, llc->p_flag, llc->f_flag,
		   llc->s_flag, llc->data_flag, llc->remote_busy_flag,
		   llc->cause_flag, timer_pending(&llc->ack_timer.timer),
		   timer_pending(&llc->pf_cycle_timer.timer),
		   timer_pending(&llc->rej_sent_timer.timer),
		   timer_pending(&llc->busy_state_timer.timer),
		   !!sk->sk_backlog.tail, sock_owned_by_user_nocheck(sk));
out:
	return 0;
}

static const struct seq_operations llc_seq_socket_ops = {
	.start  = llc_seq_start,
	.next   = llc_seq_next,
	.stop   = llc_seq_stop,
	.show   = llc_seq_socket_show,
};

static const struct seq_operations llc_seq_core_ops = {
	.start  = llc_seq_start,
	.next   = llc_seq_next,
	.stop   = llc_seq_stop,
	.show   = llc_seq_core_show,
};

static struct proc_dir_entry *llc_proc_dir;

int __init llc_proc_init(void)
{
	int rc = -ENOMEM;
	struct proc_dir_entry *p;

	llc_proc_dir = proc_mkdir("llc", init_net.proc_net);
	if (!llc_proc_dir)
		goto out;

	p = proc_create_seq("socket", 0444, llc_proc_dir, &llc_seq_socket_ops);
	if (!p)
		goto out_socket;

	p = proc_create_seq("core", 0444, llc_proc_dir, &llc_seq_core_ops);
	if (!p)
		goto out_core;

	rc = 0;
out:
	return rc;
out_core:
	remove_proc_entry("socket", llc_proc_dir);
out_socket:
	remove_proc_entry("llc", init_net.proc_net);
	goto out;
}

void llc_proc_exit(void)
{
	remove_proc_entry("socket", llc_proc_dir);
	remove_proc_entry("core", llc_proc_dir);
	remove_proc_entry("llc", init_net.proc_net);
}
