Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20c2c1fd authored by Neil Horman's avatar Neil Horman Committed by David S. Miller
Browse files

sctp: add sctp/remaddr table to complete RFC remote address table OID



Add support for RFC3873 remote address table OID.

      +--(5) sctpAssocRemAddrTable
      |   |
      |   |--(-) sctpAssocId (shared index)
      |   |
      |   +--(1) sctpAssocRemAddrType (index)
      .   |
      .   +--(2) sctpAssocRemAddr (index)
      .   |
          +--(3) sctpAssocRemAddrActive
          |
          +--(4) sctpAssocRemAddrHBActive
          |
          +--(5) sctpAssocRemAddrRTO
          |
          +--(6) sctpAssocRemAddrMaxPathRtx
          |
          +--(7) sctpAssocRemAddrRtx
          |
          +--(8) sctpAssocRemAddrStartTime

This patch places all the requsite data in /proc/net/sctp/remaddr.

Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 88a0a948
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -179,6 +179,8 @@ int sctp_eps_proc_init(void);
void sctp_eps_proc_exit(void);
void sctp_eps_proc_exit(void);
int sctp_assocs_proc_init(void);
int sctp_assocs_proc_init(void);
void sctp_assocs_proc_exit(void);
void sctp_assocs_proc_exit(void);
int sctp_remaddr_proc_init(void);
void sctp_remaddr_proc_exit(void);




/*
/*
+141 −0
Original line number Original line Diff line number Diff line
@@ -383,3 +383,144 @@ void sctp_assocs_proc_exit(void)
{
{
	remove_proc_entry("assocs", proc_net_sctp);
	remove_proc_entry("assocs", proc_net_sctp);
}
}

static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos)
{
	if (*pos >= sctp_assoc_hashsize)
		return NULL;

	if (*pos < 0)
		*pos = 0;

	if (*pos == 0)
		seq_printf(seq, "ADDR ASSOC_ID HB_ACT RTO MAX_PATH_RTX "
				"REM_ADDR_RTX  START\n");

	return (void *)pos;
}

static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	if (++*pos >= sctp_assoc_hashsize)
		return NULL;

	return pos;
}

static void sctp_remaddr_seq_stop(struct seq_file *seq, void *v)
{
	return;
}

static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
{
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;
	struct sctp_association *assoc;
	struct hlist_node *node;
	struct sctp_transport *tsp;
	int    hash = *(loff_t *)v;

	if (hash >= sctp_assoc_hashsize)
		return -ENOMEM;

	head = &sctp_assoc_hashtable[hash];
	sctp_local_bh_disable();
	read_lock(&head->lock);
	sctp_for_each_hentry(epb, node, &head->chain) {
		assoc = sctp_assoc(epb);
		list_for_each_entry(tsp, &assoc->peer.transport_addr_list,
					transports) {
			/*
			 * The remote address (ADDR)
			 */
			tsp->af_specific->seq_dump_addr(seq, &tsp->ipaddr);
			seq_printf(seq, " ");

			/*
			 * The association ID (ASSOC_ID)
			 */
			seq_printf(seq, "%d ", tsp->asoc->assoc_id);

			/*
			 * If the Heartbeat is active (HB_ACT)
			 * Note: 1 = Active, 0 = Inactive
			 */
			seq_printf(seq, "%d ", timer_pending(&tsp->hb_timer));

			/*
			 * Retransmit time out (RTO)
			 */
			seq_printf(seq, "%lu ", tsp->rto);

			/*
			 * Maximum path retransmit count (PATH_MAX_RTX)
			 */
			seq_printf(seq, "%d ", tsp->pathmaxrxt);

			/*
			 * remote address retransmit count (REM_ADDR_RTX)
			 * Note: We don't have a way to tally this at the moment
			 * so lets just leave it as zero for the moment
			 */
			seq_printf(seq, "0 ");

			/*
			 * remote address start time (START).  This is also not
			 * currently implemented, but we can record it with a
			 * jiffies marker in a subsequent patch
			 */
			seq_printf(seq, "0");

			seq_printf(seq, "\n");
		}
	}

	read_unlock(&head->lock);
	sctp_local_bh_enable();

	return 0;

}

static const struct seq_operations sctp_remaddr_ops = {
	.start = sctp_remaddr_seq_start,
	.next  = sctp_remaddr_seq_next,
	.stop  = sctp_remaddr_seq_stop,
	.show  = sctp_remaddr_seq_show,
};

/* Cleanup the proc fs entry for 'remaddr' object. */
void sctp_remaddr_proc_exit(void)
{
	remove_proc_entry("remaddr", proc_net_sctp);
}

static int sctp_remaddr_seq_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &sctp_remaddr_ops);
}

static const struct file_operations sctp_remaddr_seq_fops = {
	.open = sctp_remaddr_seq_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release,
};

int __init sctp_remaddr_proc_init(void)
{
	struct proc_dir_entry *p;

	p = create_proc_entry("remaddr", S_IRUGO, proc_net_sctp);
	if (!p)
		return -ENOMEM;
	p->proc_fops = &sctp_remaddr_seq_fops;

	return 0;
}

void sctp_assoc_proc_exit(void)
{
	remove_proc_entry("remaddr", proc_net_sctp);
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -113,6 +113,8 @@ static __init int sctp_proc_init(void)
		goto out_nomem;
		goto out_nomem;
	if (sctp_assocs_proc_init())
	if (sctp_assocs_proc_init())
		goto out_nomem;
		goto out_nomem;
	if (sctp_remaddr_proc_init())
		goto out_nomem;


	return 0;
	return 0;


@@ -129,6 +131,7 @@ static void sctp_proc_exit(void)
	sctp_snmp_proc_exit();
	sctp_snmp_proc_exit();
	sctp_eps_proc_exit();
	sctp_eps_proc_exit();
	sctp_assocs_proc_exit();
	sctp_assocs_proc_exit();
	sctp_remaddr_proc_exit();


	if (proc_net_sctp) {
	if (proc_net_sctp) {
		proc_net_sctp = NULL;
		proc_net_sctp = NULL;