]> git.neil.brown.name Git - history.git/commitdiff
o LLC: start using seq_file for proc stuff
authorArnaldo Carvalho de Melo <acme@conectiva.com.br>
Sat, 5 Oct 2002 16:13:46 +0000 (13:13 -0300)
committerArnaldo Carvalho de Melo <acme@conectiva.com.br>
Sat, 5 Oct 2002 16:13:46 +0000 (13:13 -0300)
include/net/llc_main.h
include/net/llc_proc.h [new file with mode: 0644]
net/llc/Makefile
net/llc/af_llc.c
net/llc/llc_if.c
net/llc/llc_mac.c
net/llc/llc_main.c
net/llc/llc_proc.c [new file with mode: 0644]

index 434e86044dec7b7b8dd00bf21b9dda76995ce257..0e0d39742a2e25a89f26f599611624e9b4643ab0 100644 (file)
@@ -57,10 +57,11 @@ extern struct llc_sap *llc_sap_alloc(void);
 extern void llc_sap_save(struct llc_sap *sap);
 extern void llc_free_sap(struct llc_sap *sap);
 extern struct llc_sap *llc_sap_find(u8 lsap);
-extern struct llc_station *llc_station_get(void);
 extern void llc_station_state_process(struct llc_station *station,
                                      struct sk_buff *skb);
 extern void llc_station_send_pdu(struct llc_station *station,
                                 struct sk_buff *skb);
 extern struct sk_buff *llc_alloc_frame(void);
+
+extern struct llc_station llc_main_station;
 #endif /* LLC_MAIN_H */
diff --git a/include/net/llc_proc.h b/include/net/llc_proc.h
new file mode 100644 (file)
index 0000000..c6e7306
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef LLC_PROC_H
+#define LLC_PROC_H
+/*
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ *              2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+
+extern int llc_proc_init(void);
+extern void llc_proc_exit(void);
+
+#endif /* LLC_PROC_H */
index 05ae5f67518dd15136dc011dee90a79d2dfb8b33..5c9a53fe6988417c258fafce3fb1695572913500 100644 (file)
@@ -16,7 +16,7 @@ obj-$(CONFIG_LLC) += llc.o
 
 llc-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \
         llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \
-        llc_s_ev.o llc_evnt.o llc_pdu.o
+        llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o
 llc-$(CONFIG_LLC_UI)   += af_llc.o
 llc-objs               := $(llc-y)
 
index 2144915eee5ba314cc048a545667477e9532d74f..0c99a4e6c01f4b6d8217f6cedd30a6c096ce7e1b 100644 (file)
@@ -41,6 +41,7 @@
 #include <net/llc_conn.h>
 #include <net/llc_mac.h>
 #include <net/llc_main.h>
+#include <net/llc_proc.h>
 #include <linux/llc.h>
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
@@ -1027,94 +1028,6 @@ out:
        return rc;
 }
 
-#ifdef CONFIG_PROC_FS
-#define MAC_FORMATTED_SIZE 17
-static void llc_ui_format_mac(char *bf, unsigned char *mac)
-{
-       sprintf(bf, "%02X:%02X:%02X:%02X:%02X:%02X",
-               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-}
-
-/**
- *     llc_ui_get_info - return info to procfs
- *     @buffer: where to put the formatted output
- *     @start: starting from
- *     @offset: offset into buffer.
- *     @length: size of the buffer
- *
- *     Get the output of the local llc ui socket list to the caller.
- *     Returns the length of data wrote to buffer.
- */
-static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
-{
-       off_t pos = 0;
-       off_t begin = 0;
-       struct llc_sap *sap;
-       struct sock *sk;
-       struct list_head *sap_entry;
-       struct llc_station *station = llc_station_get();
-       int len = sprintf(buffer, "SKt Mc local_mac_sap        "
-                                 "remote_mac_sap       tx_queue rx_queue st uid "
-                                 "link\n");
-
-       /* Output the LLC socket data for the /proc filesystem */
-       read_lock_bh(&station->sap_list.lock);
-       list_for_each(sap_entry, &station->sap_list.list) {
-               sap = list_entry(sap_entry, struct llc_sap, node);
-
-               read_lock_bh(&sap->sk_list.lock);
-               for (sk = sap->sk_list.list; sk; sk = sk->next) {
-                       struct llc_opt *llc = llc_sk(sk);
-
-                       len += sprintf(buffer + len, "%2X  %2X ", sk->type,
-                                      !llc_mac_null(llc->addr.sllc_mmac));
-                       if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
-                               llc_ui_format_mac(buffer + len,
-                                                 llc->dev->dev_addr);
-                       else {
-                               if (!llc_mac_null(llc->addr.sllc_mmac))
-                                       llc_ui_format_mac(buffer + len,
-                                                         llc->addr.sllc_mmac);
-                               else
-                                       sprintf(buffer + len,
-                                               "00:00:00:00:00:00");
-                       }
-                       len += MAC_FORMATTED_SIZE;
-                       len += sprintf(buffer + len, "@%02X ", sap->laddr.lsap);
-                       llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac);
-                       len += MAC_FORMATTED_SIZE;
-                       len += sprintf(buffer + len,
-                                       "@%02X %8d %8d %2d %3d ",
-                                       llc->addr.sllc_dsap,
-                                       atomic_read(&sk->wmem_alloc),
-                                       atomic_read(&sk->rmem_alloc),
-                                       sk->state,
-                                       sk->socket ?
-                                         SOCK_INODE(sk->socket)->i_uid : -1);
-                       len += sprintf(buffer + len, "%4d\n", llc->link);
-                       /* Are we still dumping unwanted data then discard the record */
-                       pos = begin + len;
-
-                       if (pos < offset) {
-                               len = 0; /* Keep dumping into the buffer start */
-                               begin = pos;
-                       }
-                       if (pos > offset + length) /* We have dumped enough */
-                               break;
-               }
-               read_unlock_bh(&sap->sk_list.lock);
-       }
-       read_unlock_bh(&station->sap_list.lock);
-
-       /* The data in question runs from begin to begin + len */
-       *start = buffer + offset - begin; /* Start of wanted data */
-       len -= offset - begin; /* Remove unwanted header data from length */
-       if (len > length)
-               len = length; /* Remove unwanted tail data from length */
-       return len;
-}
-#endif /* CONFIG_PROC_FS */
-
 static struct net_proto_family llc_ui_family_ops = {
        .family = PF_LLC,
        .create = llc_ui_create,
@@ -1145,15 +1058,20 @@ static char llc_ui_banner[] __initdata =
 
 int __init llc_ui_init(void)
 {
+       int rc = llc_proc_init();
+
+       if (rc)
+               goto out;
        llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
        sock_register(&llc_ui_family_ops);
-       proc_net_create("llc", 0, llc_ui_get_info);
        printk(llc_ui_banner);
-       return 0;
+       rc = 0;
+out:
+       return rc;
 }
 
 void __exit llc_ui_exit(void)
 {
-       proc_net_remove("llc");
        sock_unregister(PF_LLC);
+       llc_proc_exit();
 }
index 1f1d241732a635e94587ee2a8c2a1f408626fccf..ffc0771f69e41833296929060b009e06fceeb298 100644 (file)
@@ -56,7 +56,7 @@ struct llc_sap *llc_sap_open(u8 lsap, int (*func)(struct sk_buff *skb,
        /* allocated a SAP; initialize it and clear out its memory pool */
        sap->laddr.lsap = lsap;
        sap->rcv_func   = func;
-       sap->station    = llc_station_get();
+       sap->station    = &llc_main_station;
        /* initialized SAP; add it to list of SAPs this station manages */
        llc_sap_save(sap);
 out:
index ae97f73a607b47bd6b7833febce864b8b82f5ad0..3f53410df740d94df90dbcc309c6e04f20eea5a7 100644 (file)
@@ -197,12 +197,11 @@ static void fix_up_incoming_skb(struct sk_buff *skb)
  */
 static void llc_station_rcv(struct sk_buff *skb)
 {
-       struct llc_station *station = llc_station_get();
        struct llc_station_state_ev *ev = llc_station_ev(skb);
 
        ev->type   = LLC_STATION_EV_TYPE_PDU;
        ev->reason = 0;
-       llc_station_state_process(station, skb);
+       llc_station_state_process(&llc_main_station, skb);
 }
 
 
index f7b54e15882d4bcbe106d4b7753a2f776adc2190..a8167171dc6b687771219fc02809bae573650730 100644 (file)
@@ -50,7 +50,7 @@ static struct llc_station_state_trans *
                                                    struct sk_buff *skb);
 static int llc_rtn_all_conns(struct llc_sap *sap);
 
-static struct llc_station llc_main_station;    /* only one of its kind */
+struct llc_station llc_main_station;   /* only one of its kind */
 
 #undef LLC_REFCNT_DEBUG
 #ifdef LLC_REFCNT_DEBUG
@@ -339,16 +339,6 @@ static int llc_rtn_all_conns(struct llc_sap *sap)
        return rc;
 }
 
-/**
- *     llc_station_get - get addr of global station.
- *
- *     Returns address of a place to copy the global station to it.
- */
-struct llc_station *llc_station_get(void)
-{
-       return &llc_main_station;
-}
-
 /**
  *     llc_station_state_process: queue event and try to process queue.
  *     @station: Address of the station
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
new file mode 100644 (file)
index 0000000..e9f08b4
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * proc_llc.c - proc interface for LLC
+ *
+ * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
+ *              2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <asm/uaccess.h>
+#include <asm/ioctls.h>
+#include <linux/proc_fs.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/errno.h>
+#include <net/sock.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_pdu.h>
+#include <net/llc_conn.h>
+#include <net/llc_mac.h>
+#include <net/llc_main.h>
+#include <linux/llc.h>
+#include <linux/if_arp.h>
+#include <linux/rtnetlink.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+
+#ifdef CONFIG_PROC_FS
+static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac)
+{
+       seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X",
+                  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static __inline__ struct sock *llc_get_sk_idx(loff_t pos)
+{
+       struct list_head *sap_entry;
+       struct llc_sap *sap;
+       struct sock *sk = NULL;
+
+       list_for_each(sap_entry, &llc_main_station.sap_list.list) {
+               sap = list_entry(sap_entry, struct llc_sap, node);
+
+               read_lock_bh(&sap->sk_list.lock);
+               for (sk = sap->sk_list.list; pos && sk; sk = sk->next)
+                       --pos;
+               if (!pos) {
+                       if (!sk)
+                               read_unlock_bh(&sap->sk_list.lock);
+                       break;
+               }
+               read_unlock_bh(&sap->sk_list.lock);
+       }
+       return sk;
+}
+
+static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       loff_t l = *pos;
+
+       read_lock_bh(&llc_main_station.sap_list.lock);
+       if (!l)
+               return (void *)1;
+       return llc_get_sk_idx(--l);
+}
+
+static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct sock* sk;
+       struct llc_opt *llc;
+       struct llc_sap *sap;
+
+       ++*pos;
+       if (v == (void *)1) {
+               if (list_empty(&llc_main_station.sap_list.list)) {
+                       sk = NULL;
+                       goto out;
+               }
+               sap = list_entry(llc_main_station.sap_list.list.next,
+                                struct llc_sap, node);
+
+               read_lock_bh(&sap->sk_list.lock);
+               sk = sap->sk_list.list;
+               goto out;
+       }
+       sk = v;
+       if (sk->next) {
+               sk = sk->next;
+               goto out;
+       }
+       llc = llc_sk(sk);
+       sap = llc->sap;
+       read_unlock_bh(&sap->sk_list.lock);
+       sk = NULL;
+       for (;;) {
+               if (sap->node.next == &llc_main_station.sap_list.list)
+                       break;
+               sap = list_entry(sap->node.next, struct llc_sap, node);
+               read_lock_bh(&sap->sk_list.lock);
+               if (sap->sk_list.list) {
+                       sk = sap->sk_list.list;
+                       break;
+               }
+               read_unlock_bh(&sap->sk_list.lock);
+       }
+out:
+       return sk;
+}
+
+static void llc_seq_stop(struct seq_file *seq, void *v)
+{
+       read_unlock_bh(&llc_main_station.sap_list.lock);
+}
+
+static int llc_seq_show(struct seq_file *seq, void *v)
+{
+       struct sock* sk;
+       struct llc_opt *llc;
+
+       if (v == (void *)1) {
+               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);
+
+       seq_printf(seq, "%2X  %2X ", sk->type,
+                  !llc_mac_null(llc->addr.sllc_mmac));
+
+       if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
+               llc_ui_format_mac(seq, llc->dev->dev_addr);
+       else if (!llc_mac_null(llc->addr.sllc_mmac))
+               llc_ui_format_mac(seq, llc->addr.sllc_mmac);
+       else
+               seq_printf(seq, "00:00:00:00:00:00");
+       seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
+       llc_ui_format_mac(seq, llc->addr.sllc_dmac);
+       seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->addr.sllc_dsap,
+                  atomic_read(&sk->wmem_alloc), atomic_read(&sk->rmem_alloc),
+                  sk->state, sk->socket ? SOCK_INODE(sk->socket)->i_uid : -1,
+                  llc->link);
+out:
+       return 0;
+}
+
+struct seq_operations llc_seq_ops = {
+       .start  = llc_seq_start,
+       .next   = llc_seq_next,
+       .stop   = llc_seq_stop,
+       .show   = llc_seq_show,
+};
+
+static int llc_seq_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &llc_seq_ops);
+}
+
+static int llc_proc_perms(struct inode* inode, int op)
+{
+       return 0;
+}
+
+static struct file_operations llc_seq_fops = {
+       .open           = llc_seq_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static struct inode_operations llc_seq_inode = {
+       .permission     = llc_proc_perms,
+};
+
+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", proc_net);
+       if (!llc_proc_dir)
+               goto out;
+
+       p = create_proc_entry("socket", 0, llc_proc_dir);
+       if (!p)
+               goto out_socket;
+
+       p->proc_fops = &llc_seq_fops;
+       p->proc_iops = &llc_seq_inode;
+       rc = 0;
+out:
+       return rc;
+out_socket:
+       remove_proc_entry("llc", proc_net);
+       goto out;
+}
+
+void __exit llc_proc_exit(void)
+{
+       remove_proc_entry("socket", llc_proc_dir);
+       remove_proc_entry("llc", proc_net);
+}
+#else /* CONFIG_PROC_FS */
+int __init llc_proc_init(void)
+{
+       return 0;
+}
+
+void __exit llc_proc_exit(void)
+{
+}
+#endif /* CONFIG_PROC_FS */