sctp: add sctp/remaddr table to complete RFC remote address table OID
authorNeil Horman <nhorman@tuxdriver.com>
Fri, 9 May 2008 22:14:50 +0000 (15:14 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 May 2008 22:14:50 +0000 (15:14 -0700)
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: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/sctp.h
net/sctp/proc.c
net/sctp/protocol.c

index 90b1e8d..5672d48 100644 (file)
@@ -179,6 +179,8 @@ int sctp_eps_proc_init(void);
 void sctp_eps_proc_exit(void);
 int sctp_assocs_proc_init(void);
 void sctp_assocs_proc_exit(void);
+int sctp_remaddr_proc_init(void);
+void sctp_remaddr_proc_exit(void);
 
 
 /*
index 0aba759..5dd8983 100644 (file)
@@ -383,3 +383,144 @@ void sctp_assocs_proc_exit(void)
 {
        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);
+}
index 0ec234b..b8bd9e0 100644 (file)
@@ -113,6 +113,8 @@ static __init int sctp_proc_init(void)
                goto out_nomem;
        if (sctp_assocs_proc_init())
                goto out_nomem;
+       if (sctp_remaddr_proc_init())
+               goto out_nomem;
 
        return 0;
 
@@ -129,6 +131,7 @@ static void sctp_proc_exit(void)
        sctp_snmp_proc_exit();
        sctp_eps_proc_exit();
        sctp_assocs_proc_exit();
+       sctp_remaddr_proc_exit();
 
        if (proc_net_sctp) {
                proc_net_sctp = NULL;