Commit a87706c2 authored by David S. Miller's avatar David S. Miller

Merge master.kernel.org:/home/acme/BK/x25-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 23c54087 38c81322
...@@ -220,9 +220,8 @@ extern void x25_enquiry_response(struct sock *); ...@@ -220,9 +220,8 @@ extern void x25_enquiry_response(struct sock *);
/* x25_route.c */ /* x25_route.c */
extern struct x25_route *x25_get_route(struct x25_address *addr); extern struct x25_route *x25_get_route(struct x25_address *addr);
extern struct net_device *x25_dev_get(char *); extern struct net_device *x25_dev_get(char *);
extern void x25_route_device_down(struct net_device *); extern void x25_route_device_down(struct net_device *dev);
extern int x25_route_ioctl(unsigned int, void *); extern int x25_route_ioctl(unsigned int, void *);
extern int x25_routes_get_info(char *, char **, off_t, int);
extern void x25_route_free(void); extern void x25_route_free(void);
static __inline__ void x25_route_hold(struct x25_route *rt) static __inline__ void x25_route_hold(struct x25_route *rt)
...@@ -263,4 +262,12 @@ struct x25_skb_cb { ...@@ -263,4 +262,12 @@ struct x25_skb_cb {
unsigned flags; unsigned flags;
}; };
#define X25_SKB_CB(s) ((struct x25_skb_cb *) ((s)->cb)) #define X25_SKB_CB(s) ((struct x25_skb_cb *) ((s)->cb))
extern struct sock *x25_list;
extern rwlock_t x25_list_lock;
extern struct list_head x25_route_list;
extern rwlock_t x25_route_list_lock;
extern int x25_proc_init(void);
extern void x25_proc_exit(void);
#endif #endif
...@@ -61,9 +61,6 @@ typedef struct wan_stat_entry ...@@ -61,9 +61,6 @@ typedef struct wan_stat_entry
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
/* Proc filesystem interface */
static int router_proc_perms(struct inode *, int);
/* Miscellaneous */ /* Miscellaneous */
/* /*
...@@ -79,11 +76,6 @@ static int router_proc_perms(struct inode *, int); ...@@ -79,11 +76,6 @@ static int router_proc_perms(struct inode *, int);
* Generic /proc/net/router/<file> file and inode operations * Generic /proc/net/router/<file> file and inode operations
*/ */
static struct inode_operations router_inode =
{
.permission = router_proc_perms,
};
/* /*
* /proc/net/router * /proc/net/router
*/ */
...@@ -98,15 +90,6 @@ static struct proc_dir_entry *proc_router; ...@@ -98,15 +90,6 @@ static struct proc_dir_entry *proc_router;
/****** Proc filesystem entry points ****************************************/ /****** Proc filesystem entry points ****************************************/
/*
* Verify access rights.
*/
static int router_proc_perms (struct inode* inode, int op)
{
return 0;
}
/* /*
* Iterator * Iterator
*/ */
...@@ -320,16 +303,14 @@ int __init wanrouter_proc_init (void) ...@@ -320,16 +303,14 @@ int __init wanrouter_proc_init (void)
if (!proc_router) if (!proc_router)
goto fail; goto fail;
p = create_proc_entry("config",0,proc_router); p = create_proc_entry("config", S_IRUGO, proc_router);
if (!p) if (!p)
goto fail_config; goto fail_config;
p->proc_fops = &config_fops; p->proc_fops = &config_fops;
p->proc_iops = &router_inode; p = create_proc_entry("status", S_IRUGO, proc_router);
p = create_proc_entry("status",0,proc_router);
if (!p) if (!p)
goto fail_stat; goto fail_stat;
p->proc_fops = &status_fops; p->proc_fops = &status_fops;
p->proc_iops = &router_inode;
return 0; return 0;
fail_stat: fail_stat:
remove_proc_entry("config", proc_router); remove_proc_entry("config", proc_router);
...@@ -359,11 +340,10 @@ int wanrouter_proc_add (wan_device_t* wandev) ...@@ -359,11 +340,10 @@ int wanrouter_proc_add (wan_device_t* wandev)
if (wandev->magic != ROUTER_MAGIC) if (wandev->magic != ROUTER_MAGIC)
return -EINVAL; return -EINVAL;
wandev->dent = create_proc_entry(wandev->name, 0, proc_router); wandev->dent = create_proc_entry(wandev->name, S_IRUGO, proc_router);
if (!wandev->dent) if (!wandev->dent)
return -ENOMEM; return -ENOMEM;
wandev->dent->proc_fops = &wandev_fops; wandev->dent->proc_fops = &wandev_fops;
wandev->dent->proc_iops = &router_inode;
wandev->dent->data = wandev; wandev->dent->data = wandev;
return 0; return 0;
} }
......
...@@ -6,7 +6,7 @@ obj-$(CONFIG_X25) += x25.o ...@@ -6,7 +6,7 @@ obj-$(CONFIG_X25) += x25.o
x25-y := af_x25.o x25_dev.o x25_facilities.o x25_in.o \ x25-y := af_x25.o x25_dev.o x25_facilities.o x25_in.o \
x25_link.o x25_out.o x25_route.o x25_subr.o \ x25_link.o x25_out.o x25_route.o x25_subr.o \
x25_timer.o x25_timer.o x25_proc.o
x25-$(CONFIG_SYSCTL) += sysctl_net_x25.o x25-$(CONFIG_SYSCTL) += sysctl_net_x25.o
x25-objs := $(x25-y) x25-objs := $(x25-y)
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
* 2000-10-02 Henner Eisen Made x25_kick() single threaded per socket. * 2000-10-02 Henner Eisen Made x25_kick() single threaded per socket.
* 2000-10-27 Henner Eisen MSG_DONTWAIT for fragment allocation. * 2000-10-27 Henner Eisen MSG_DONTWAIT for fragment allocation.
* 2000-11-14 Henner Eisen Closing datalink from NETDEV_GOING_DOWN * 2000-11-14 Henner Eisen Closing datalink from NETDEV_GOING_DOWN
* 2002-10-06 Arnaldo C. Melo Get rid of cli/sti, move proc stuff to
* x25_proc.c, using seq_file
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -55,7 +57,6 @@ ...@@ -55,7 +57,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/init.h> #include <linux/init.h>
#include <net/x25.h> #include <net/x25.h>
...@@ -65,8 +66,8 @@ int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22; ...@@ -65,8 +66,8 @@ int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22;
int sysctl_x25_clear_request_timeout = X25_DEFAULT_T23; int sysctl_x25_clear_request_timeout = X25_DEFAULT_T23;
int sysctl_x25_ack_holdback_timeout = X25_DEFAULT_T2; int sysctl_x25_ack_holdback_timeout = X25_DEFAULT_T2;
static struct sock *x25_list; struct sock *x25_list;
static rwlock_t x25_list_lock = RW_LOCK_UNLOCKED; rwlock_t x25_list_lock = RW_LOCK_UNLOCKED;
static struct proto_ops x25_proto_ops; static struct proto_ops x25_proto_ops;
...@@ -246,8 +247,10 @@ static struct sock *x25_find_listener(struct x25_address *addr) ...@@ -246,8 +247,10 @@ static struct sock *x25_find_listener(struct x25_address *addr)
read_lock_bh(&x25_list_lock); read_lock_bh(&x25_list_lock);
for (s = x25_list; s; s = s->next) for (s = x25_list; s; s = s->next)
if ((!strcmp(addr->x25_addr, x25_sk(s)->source_addr.x25_addr) || if ((!strcmp(addr->x25_addr,
!strcmp(addr->x25_addr, null_x25_address.x25_addr)) && x25_sk(s)->source_addr.x25_addr) ||
!strcmp(addr->x25_addr,
null_x25_address.x25_addr)) &&
s->state == TCP_LISTEN) s->state == TCP_LISTEN)
break; break;
...@@ -318,12 +321,13 @@ static void x25_destroy_timer(unsigned long data) ...@@ -318,12 +321,13 @@ static void x25_destroy_timer(unsigned long data)
} }
/* /*
* This is called from user mode and the timers. Thus it protects itself against * This is called from user mode and the timers. Thus it protects itself
* interrupt users but doesn't worry about being called during work. * against interrupt users but doesn't worry about being called during
* Once it is removed from the queue no interrupt or bottom half will * work. Once it is removed from the queue no interrupt or bottom half
* touch it and we are (fairly 8-) ) safe. * will touch it and we are (fairly 8-) ) safe.
* Not static as it's used by the timer
*/ */
void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer */ void x25_destroy_socket(struct sock *sk)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -337,7 +341,10 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer ...@@ -337,7 +341,10 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) { while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
if (skb->sk != sk) { /* A pending connection */ if (skb->sk != sk) { /* A pending connection */
skb->sk->dead = 1; /* Queue the unaccepted socket for death */ /*
* Queue the unaccepted socket for death
*/
skb->sk->dead = 1;
x25_start_heartbeat(skb->sk); x25_start_heartbeat(skb->sk);
x25_sk(skb->sk)->state = X25_STATE_0; x25_sk(skb->sk)->state = X25_STATE_0;
} }
...@@ -631,7 +638,8 @@ static int x25_wait_for_connection_establishment(struct sock *sk) ...@@ -631,7 +638,8 @@ static int x25_wait_for_connection_establishment(struct sock *sk)
return rc; return rc;
} }
static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct x25_opt *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
...@@ -642,7 +650,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len ...@@ -642,7 +650,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
lock_sock(sk); lock_sock(sk);
if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
goto out; /* Connect completed during a ERESTARTSYS event */ goto out; /* Connect completed during a ERESTARTSYS event */
} }
rc = -ECONNREFUSED; rc = -ECONNREFUSED;
...@@ -679,7 +687,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len ...@@ -679,7 +687,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
goto out_put_neigh; goto out_put_neigh;
rc = -EINVAL; rc = -EINVAL;
if (sk->zapped) /* Must bind first - autobinding does not work */ if (sk->zapped) /* Must bind first - autobinding does not work */
goto out_put_neigh; goto out_put_neigh;
if (!strcmp(x25->source_addr.x25_addr, null_x25_address.x25_addr)) if (!strcmp(x25->source_addr.x25_addr, null_x25_address.x25_addr))
...@@ -785,7 +793,8 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -785,7 +793,8 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
return rc; return rc;
} }
static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
int *uaddr_len, int peer)
{ {
struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr; struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -804,7 +813,8 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l ...@@ -804,7 +813,8 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l
return 0; return 0;
} }
int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int lci) int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
unsigned int lci)
{ {
struct sock *sk; struct sock *sk;
struct sock *make; struct sock *make;
...@@ -906,7 +916,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int ...@@ -906,7 +916,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
goto out; goto out;
} }
static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len,
struct scm_cookie *scm)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct x25_opt *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
...@@ -1118,7 +1129,8 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, ...@@ -1118,7 +1129,8 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size,
msg->msg_flags |= MSG_OOB; msg->msg_flags |= MSG_OOB;
} else { } else {
/* Now we can treat all alike */ /* Now we can treat all alike */
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &rc); skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &rc);
if (!skb) if (!skb)
goto out; goto out;
...@@ -1236,14 +1248,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1236,14 +1248,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break; break;
case SIOCX25GFACILITIES: { case SIOCX25GFACILITIES: {
struct x25_facilities fac = x25->facilities; struct x25_facilities fac = x25->facilities;
rc = copy_to_user((void *)arg, &fac, sizeof(fac)) ? -EFAULT : 0; rc = copy_to_user((void *)arg, &fac,
sizeof(fac)) ? -EFAULT : 0;
break; break;
} }
case SIOCX25SFACILITIES: { case SIOCX25SFACILITIES: {
struct x25_facilities facilities; struct x25_facilities facilities;
rc = -EFAULT; rc = -EFAULT;
if (copy_from_user(&facilities, (void *)arg, sizeof(facilities))) if (copy_from_user(&facilities, (void *)arg,
sizeof(facilities)))
break; break;
rc = -EINVAL; rc = -EINVAL;
if (sk->state != TCP_LISTEN && sk->state != TCP_CLOSE) if (sk->state != TCP_LISTEN && sk->state != TCP_CLOSE)
...@@ -1269,7 +1283,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1269,7 +1283,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCX25GCALLUSERDATA: { case SIOCX25GCALLUSERDATA: {
struct x25_calluserdata cud = x25->calluserdata; struct x25_calluserdata cud = x25->calluserdata;
rc = copy_to_user((void *)arg, &cud, sizeof(cud)) ? -EFAULT : 0; rc = copy_to_user((void *)arg, &cud,
sizeof(cud)) ? -EFAULT : 0;
break; break;
} }
...@@ -1277,7 +1292,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1277,7 +1292,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct x25_calluserdata calluserdata; struct x25_calluserdata calluserdata;
rc = -EFAULT; rc = -EFAULT;
if (copy_from_user(&calluserdata, (void *)arg, sizeof(calluserdata))) if (copy_from_user(&calluserdata, (void *)arg,
sizeof(calluserdata)))
break; break;
rc = -EINVAL; rc = -EINVAL;
if (calluserdata.cudlength > X25_MAX_CUD_LEN) if (calluserdata.cudlength > X25_MAX_CUD_LEN)
...@@ -1290,7 +1306,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1290,7 +1306,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCX25GCAUSEDIAG: { case SIOCX25GCAUSEDIAG: {
struct x25_causediag causediag; struct x25_causediag causediag;
causediag = x25->causediag; causediag = x25->causediag;
rc = copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0; rc = copy_to_user((void *)arg, &causediag,
sizeof(causediag)) ? -EFAULT : 0;
break; break;
} }
...@@ -1302,70 +1319,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1302,70 +1319,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return rc; return rc;
} }
static int x25_get_info(char *buffer, char **start, off_t offset, int length)
{
struct sock *s;
struct net_device *dev;
const char *devname;
off_t pos = 0;
off_t begin = 0;
int len = sprintf(buffer, "dest_addr src_addr dev lci st vs vr "
"va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
read_lock_bh(&x25_list_lock);
for (s = x25_list; s; s = s->next) {
struct x25_opt *x25 = x25_sk(s);
if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
devname = "???";
else
devname = x25->neighbour->dev->name;
len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X %d %d "
"%d %d %3lu %3lu %3lu %3lu %3lu "
"%5d %5d %ld\n",
!x25->dest_addr.x25_addr[0] ? "*" :
x25->dest_addr.x25_addr,
!x25->source_addr.x25_addr[0] ? "*" :
x25->source_addr.x25_addr,
devname,
x25->lci & 0x0FFF,
x25->state,
x25->vs,
x25->vr,
x25->va,
x25_display_timer(s) / HZ,
x25->t2 / HZ,
x25->t21 / HZ,
x25->t22 / HZ,
x25->t23 / HZ,
atomic_read(&s->wmem_alloc),
atomic_read(&s->rmem_alloc),
s->socket ? SOCK_INODE(s->socket)->i_ino : 0L);
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length)
break;
}
read_unlock_bh(&x25_list_lock);
*start = buffer + (offset - begin);
len -= (offset - begin);
if (len > length)
len = length;
return len;
}
struct net_proto_family x25_family_ops = { struct net_proto_family x25_family_ops = {
.family = AF_X25, .family = AF_X25,
.create = x25_create, .create = x25_create,
...@@ -1395,7 +1348,6 @@ static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { ...@@ -1395,7 +1348,6 @@ static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
SOCKOPS_WRAP(x25_proto, AF_X25); SOCKOPS_WRAP(x25_proto, AF_X25);
static struct packet_type x25_packet_type = { static struct packet_type x25_packet_type = {
.type = __constant_htons(ETH_P_X25), .type = __constant_htons(ETH_P_X25),
.func = x25_lapb_receive_frame, .func = x25_lapb_receive_frame,
...@@ -1435,9 +1387,7 @@ static int __init x25_init(void) ...@@ -1435,9 +1387,7 @@ static int __init x25_init(void)
x25_register_sysctl(); x25_register_sysctl();
#endif #endif
proc_net_create("x25", 0, x25_get_info); x25_proc_init();
proc_net_create("x25_routes", 0, x25_routes_get_info);
#ifdef MODULE #ifdef MODULE
/* /*
* Register any pre existing devices. * Register any pre existing devices.
...@@ -1457,18 +1407,9 @@ static int __init x25_init(void) ...@@ -1457,18 +1407,9 @@ static int __init x25_init(void)
} }
module_init(x25_init); module_init(x25_init);
MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
MODULE_LICENSE("GPL");
static void __exit x25_exit(void) static void __exit x25_exit(void)
{ {
x25_proc_exit();
proc_net_remove("x25");
proc_net_remove("x25_routes");
x25_link_free(); x25_link_free();
x25_route_free(); x25_route_free();
...@@ -1484,3 +1425,6 @@ static void __exit x25_exit(void) ...@@ -1484,3 +1425,6 @@ static void __exit x25_exit(void)
} }
module_exit(x25_exit); module_exit(x25_exit);
MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
MODULE_LICENSE("GPL");
/*
* X.25 Packet Layer release 002
*
* This is ALPHA test software. This code may break your machine,
* randomly fail to work with new releases, misbehave and/or generally
* screw up. It might even work.
*
* This code REQUIRES 2.4 with seq_file support
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* 2002/10/06 Arnaldo Carvalho de Melo seq_file support
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/sock.h>
#include <net/x25.h>
#ifdef CONFIG_PROC_FS
static __inline__ struct x25_route *x25_get_route_idx(loff_t pos)
{
struct list_head *route_entry;
struct x25_route *rt = NULL;
list_for_each(route_entry, &x25_route_list) {
rt = list_entry(route_entry, struct x25_route, node);
if (--pos)
break;
}
return rt;
}
static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
{
loff_t l = *pos;
read_lock_bh(&x25_route_list_lock);
return l ? x25_get_route_idx(--l) : (void *)1;
}
static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct x25_route *rt;
++*pos;
if (v == (void *)1) {
rt = NULL;
if (!list_empty(&x25_route_list))
rt = list_entry(x25_route_list.next,
struct x25_route, node);
goto out;
}
rt = v;
if (rt->node.next != &x25_route_list)
rt = list_entry(rt->node.next, struct x25_route, node);
else
rt = NULL;
out:
return rt;
}
static void x25_seq_route_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&x25_route_list_lock);
}
static int x25_seq_route_show(struct seq_file *seq, void *v)
{
struct x25_route *rt;
if (v == (void *)1) {
seq_puts(seq, "Address Digits Device\n");
goto out;
}
rt = v;
seq_printf(seq, "%-15s %-6d %-5s\n",
rt->address.x25_addr, rt->sigdigits,
rt->dev ? rt->dev->name : "???");
out:
return 0;
}
static __inline__ struct sock *x25_get_socket_idx(loff_t pos)
{
struct sock *s;
for (s = x25_list; pos && s; s = s->next)
--pos;
return s;
}
static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
{
loff_t l = *pos;
read_lock_bh(&x25_list_lock);
return l ? x25_get_socket_idx(--l) : (void *)1;
}
static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *s;
++*pos;
if (v == (void *)1) {
s = NULL;
if (x25_list)
s = x25_list;
goto out;
}
s = v;
s = s->next;
out:
return s;
}
static void x25_seq_socket_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&x25_list_lock);
}
static int x25_seq_socket_show(struct seq_file *seq, void *v)
{
struct sock *s;
struct x25_opt *x25;
struct net_device *dev;
const char *devname;
if (v == (void *)1) {
seq_printf(seq, "dest_addr src_addr dev lci st vs vr "
"va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
goto out;
}
s = v;
x25 = x25_sk(s);
if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
devname = "???";
else
devname = x25->neighbour->dev->name;
seq_printf(seq, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu "
"%3lu %3lu %3lu %5d %5d %ld\n",
!x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
!x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ,
x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc),
s->socket ? SOCK_INODE(s->socket)->i_ino : 0L);
out:
return 0;
}
struct seq_operations x25_seq_route_ops = {
.start = x25_seq_route_start,
.next = x25_seq_route_next,
.stop = x25_seq_route_stop,
.show = x25_seq_route_show,
};
struct seq_operations x25_seq_socket_ops = {
.start = x25_seq_socket_start,
.next = x25_seq_socket_next,
.stop = x25_seq_socket_stop,
.show = x25_seq_socket_show,
};
static int x25_seq_socket_open(struct inode *inode, struct file *file)
{
return seq_open(file, &x25_seq_socket_ops);
}
static int x25_seq_route_open(struct inode *inode, struct file *file)
{
return seq_open(file, &x25_seq_route_ops);
}
static struct file_operations x25_seq_socket_fops = {
.open = x25_seq_socket_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct file_operations x25_seq_route_fops = {
.open = x25_seq_route_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct proc_dir_entry *x25_proc_dir;
int __init x25_proc_init(void)
{
struct proc_dir_entry *p;
int rc = -ENOMEM;
x25_proc_dir = proc_mkdir("x25", proc_net);
if (!x25_proc_dir)
goto out;
p = create_proc_entry("route", S_IRUGO, x25_proc_dir);
if (!p)
goto out_route;
p->proc_fops = &x25_seq_route_fops;
p = create_proc_entry("socket", S_IRUGO, x25_proc_dir);
if (!p)
goto out_socket;
p->proc_fops = &x25_seq_socket_fops;
rc = 0;
out:
return rc;
out_socket:
remove_proc_entry("route", x25_proc_dir);
out_route:
remove_proc_entry("x25", proc_net);
goto out;
}
void __exit x25_proc_exit(void)
{
remove_proc_entry("route", x25_proc_dir);
remove_proc_entry("socket", x25_proc_dir);
remove_proc_entry("x25", proc_net);
}
#else /* CONFIG_PROC_FS */
int __init x25_proc_init(void)
{
return 0;
}
void __exit x25_proc_exit(void)
{
}
#endif /* CONFIG_PROC_FS */
...@@ -18,34 +18,12 @@ ...@@ -18,34 +18,12 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <net/arp.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/fcntl.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/init.h> #include <linux/init.h>
#include <net/x25.h> #include <net/x25.h>
static struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list); struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list);
static rwlock_t x25_route_list_lock = RW_LOCK_UNLOCKED; rwlock_t x25_route_list_lock = RW_LOCK_UNLOCKED;
/* /*
* Add a new route. * Add a new route.
...@@ -226,45 +204,6 @@ int x25_route_ioctl(unsigned int cmd, void *arg) ...@@ -226,45 +204,6 @@ int x25_route_ioctl(unsigned int cmd, void *arg)
return rc; return rc;
} }
int x25_routes_get_info(char *buffer, char **start, off_t offset, int length)
{
struct x25_route *rt;
struct list_head *entry;
off_t pos = 0;
off_t begin = 0;
int len = sprintf(buffer, "address digits device\n");
read_lock_bh(&x25_route_list_lock);
list_for_each(entry, &x25_route_list) {
rt = list_entry(entry, struct x25_route, node);
len += sprintf(buffer + len, "%-15s %-6d %-5s\n",
rt->address.x25_addr,
rt->sigdigits,
rt->dev ? rt->dev->name : "???");
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length)
break;
}
read_unlock_bh(&x25_route_list_lock);
*start = buffer + (offset - begin);
len -= (offset - begin);
if (len > length)
len = length;
return len;
}
/* /*
* Release all memory associated with X.25 routing structures. * Release all memory associated with X.25 routing structures.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment