Commit 6a83d262 authored by Steven Whitehouse's avatar Steven Whitehouse Committed by David S. Miller

[DECNET]: seq file conversions and fixes.

  o Removed blksize from decnet device parameters - use the device mtu like we
    ought to.
  o Removed /proc/net/decnet_route file - I don't think anybody ever used it
    and it was lacking a full enough description of the routes to be useful.
    ip -D route list is much better :-)
  o Added rt_local_src entry to decnet routes so that we get the local source
    address right when forwarding.
  o Added correct proto argument to struct flowi for routing
  o MSG_MORE in sendmsg (ignored, but accepted whereas before we'd error)
  o /proc/net/decnet converted to seq_file
  o /proc/net/decnet_dev converted to seq_file
  o /proc/net/decnet_cache converted to seq_file
  o Use pskb_may_pull() and add code to linearize skbs on the input path
    except for those containing data.
  o Fixed returned packet code (mostly - some left to do)
  o update_pmtu() method for decnet dst entries (ip_gre device assumes this
    method exists - well I think it does :-)
  o Fixed bug in forwarding to get IE bit set correctly
  o Fixed compile bugs with CONFIG_DECNET_ROUTE_FWMARK pointed out by Adrian
    Bunk
  o Fixed zero dest code to grab an address from loopback
  o Fixed local routes in dn_route_output_slow()
  o Fixed error case in dn_route_input/output_slow() pointed out by Rusty
parent acec7ca3
...@@ -71,7 +71,6 @@ struct dn_dev_parms { ...@@ -71,7 +71,6 @@ struct dn_dev_parms {
#define DN_DEV_MPOINT 4 #define DN_DEV_MPOINT 4
int state; /* Initial state */ int state; /* Initial state */
int forwarding; /* 0=EndNode, 1=L1Router, 2=L2Router */ int forwarding; /* 0=EndNode, 1=L1Router, 2=L2Router */
unsigned short blksize; /* Block Size */
unsigned long t2; /* Default value of t2 */ unsigned long t2; /* Default value of t2 */
unsigned long t3; /* Default value of t3 */ unsigned long t3; /* Default value of t3 */
int priority; /* Priority to be a router */ int priority; /* Priority to be a router */
......
...@@ -101,10 +101,6 @@ struct dn_fib_table { ...@@ -101,10 +101,6 @@ struct dn_fib_table {
int (*lookup)(struct dn_fib_table *t, const struct flowi *fl, int (*lookup)(struct dn_fib_table *t, const struct flowi *fl,
struct dn_fib_res *res); struct dn_fib_res *res);
int (*flush)(struct dn_fib_table *t); int (*flush)(struct dn_fib_table *t);
#ifdef CONFIG_PROC_FS
int (*get_info)(struct dn_fib_table *table, char *buf,
int first, int count);
#endif /* CONFIG_PROC_FS */
int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb); int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb);
unsigned char data[0]; unsigned char data[0];
...@@ -184,6 +180,9 @@ extern struct dn_fib_table *dn_fib_tables[]; ...@@ -184,6 +180,9 @@ extern struct dn_fib_table *dn_fib_tables[];
#else /* Endnode */ #else /* Endnode */
#define dn_fib_init() (0)
#define dn_fib_cleanup() (0)
#define dn_fib_lookup(fl, res) (-ESRCH) #define dn_fib_lookup(fl, res) (-ESRCH)
#define dn_fib_info_put(fi) do { } while(0) #define dn_fib_info_put(fi) do { } while(0)
#define dn_fib_select_multipath(fl, res) do { } while(0) #define dn_fib_select_multipath(fl, res) do { } while(0)
......
...@@ -74,7 +74,7 @@ struct dn_route { ...@@ -74,7 +74,7 @@ struct dn_route {
__u16 rt_saddr; __u16 rt_saddr;
__u16 rt_daddr; __u16 rt_daddr;
__u16 rt_gateway; __u16 rt_gateway;
__u16 __padding; __u16 rt_local_src; /* Source used for forwarding packets */
__u16 rt_src_map; __u16 rt_src_map;
__u16 rt_dst_map; __u16 rt_dst_map;
......
...@@ -23,15 +23,9 @@ Steve's quick list of things that need finishing off: ...@@ -23,15 +23,9 @@ Steve's quick list of things that need finishing off:
o check MSG_CTRUNC is set where it should be. o check MSG_CTRUNC is set where it should be.
o Start to hack together user level software and add more DECnet support
in ifconfig for example.
o Find all the commonality between DECnet and IPv4 routing code and extract o Find all the commonality between DECnet and IPv4 routing code and extract
it into a small library of routines. [probably a project for 2.7.xx] it into a small library of routines. [probably a project for 2.7.xx]
o Add the routing message grabbing netfilter module [written, tested,
awaiting merge]
o Add perfect socket hashing - an idea suggested by Paul Koning. Currently o Add perfect socket hashing - an idea suggested by Paul Koning. Currently
we have a half-way house scheme which seems to work reasonably well, but we have a half-way house scheme which seems to work reasonably well, but
the full scheme is still worth implementing, its not not top of my list the full scheme is still worth implementing, its not not top of my list
...@@ -45,5 +39,3 @@ Steve's quick list of things that need finishing off: ...@@ -45,5 +39,3 @@ Steve's quick list of things that need finishing off:
o AIO for DECnet o AIO for DECnet
o Eliminate dn_db->parms.blksize
...@@ -116,6 +116,7 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat ...@@ -116,6 +116,7 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/route.h> #include <linux/route.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/seq_file.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/flow.h> #include <net/flow.h>
...@@ -676,45 +677,6 @@ char *dn_addr2asc(dn_address addr, char *buf) ...@@ -676,45 +677,6 @@ char *dn_addr2asc(dn_address addr, char *buf)
} }
static char *dn_state2asc(unsigned char state)
{
switch(state) {
case DN_O:
return "OPEN";
case DN_CR:
return " CR";
case DN_DR:
return " DR";
case DN_DRC:
return " DRC";
case DN_CC:
return " CC";
case DN_CI:
return " CI";
case DN_NR:
return " NR";
case DN_NC:
return " NC";
case DN_CD:
return " CD";
case DN_RJ:
return " RJ";
case DN_RUN:
return " RUN";
case DN_DI:
return " DI";
case DN_DIC:
return " DIC";
case DN_DN:
return " DN";
case DN_CL:
return " CL";
case DN_CN:
return " CN";
}
return "????";
}
static int dn_create(struct socket *sock, int protocol) static int dn_create(struct socket *sock, int protocol)
{ {
...@@ -1001,6 +963,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen, ...@@ -1001,6 +963,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen,
fl.fld_dst = dn_saddr2dn(&scp->peer); fl.fld_dst = dn_saddr2dn(&scp->peer);
fl.fld_src = dn_saddr2dn(&scp->addr); fl.fld_src = dn_saddr2dn(&scp->addr);
dn_sk_ports_copy(&fl, scp); dn_sk_ports_copy(&fl, scp);
fl.proto = DNPROTO_NSP;
if (dn_route_output_sock(&sk->dst_cache, &fl, sk, flags) < 0) if (dn_route_output_sock(&sk->dst_cache, &fl, sk, flags) < 0)
goto out; goto out;
sk->route_caps = sk->dst_cache->dev->features; sk->route_caps = sk->dst_cache->dev->features;
...@@ -1964,7 +1927,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1964,7 +1927,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
unsigned char fctype; unsigned char fctype;
long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL)) if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (addr_len && (addr_len != sizeof(struct sockaddr_dn))) if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
...@@ -2143,6 +2106,95 @@ static struct packet_type dn_dix_packet_type = { ...@@ -2143,6 +2106,95 @@ static struct packet_type dn_dix_packet_type = {
.data = (void*)1, .data = (void*)1,
}; };
#ifdef CONFIG_PROC_FS
struct dn_iter_state {
int bucket;
};
static struct sock *dn_socket_get_first(struct seq_file *seq)
{
struct dn_iter_state *state = seq->private;
struct sock *n = NULL;
for(state->bucket = 0;
state->bucket < DN_SK_HASH_SIZE;
++state->bucket) {
n = dn_sk_hash[state->bucket];
if (n)
break;
}
return n;
}
static struct sock *dn_socket_get_next(struct seq_file *seq,
struct sock *n)
{
struct dn_iter_state *state = seq->private;
n = n->next;
try_again:
if (n)
goto out;
if (++state->bucket >= DN_SK_HASH_SIZE)
goto out;
n = dn_sk_hash[state->bucket];
goto try_again;
out:
return n;
}
static struct sock *socket_get_idx(struct seq_file *seq, loff_t *pos)
{
struct sock *sk = dn_socket_get_first(seq);
if (sk) {
while(*pos && (sk = dn_socket_get_next(seq, sk)))
--*pos;
}
return *pos ? NULL : sk;
}
static void *dn_socket_get_idx(struct seq_file *seq, loff_t pos)
{
void *rc;
read_lock_bh(&dn_hash_lock);
rc = socket_get_idx(seq, &pos);
if (!rc) {
read_unlock_bh(&dn_hash_lock);
}
return rc;
}
static void *dn_socket_seq_start(struct seq_file *seq, loff_t *pos)
{
return *pos ? dn_socket_get_idx(seq, *pos - 1) : (void*)1;
}
static void *dn_socket_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
void *rc;
if (v == (void*)1) {
rc = dn_socket_get_idx(seq, 0);
goto out;
}
rc = dn_socket_get_next(seq, v);
if (rc)
goto out;
read_unlock_bh(&dn_hash_lock);
out:
++*pos;
return rc;
}
static void dn_socket_seq_stop(struct seq_file *seq, void *v)
{
if (v && v != (void*)1)
read_unlock_bh(&dn_hash_lock);
}
#define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126) #define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126)
static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf) static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
...@@ -2163,70 +2215,127 @@ static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf) ...@@ -2163,70 +2215,127 @@ static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
} }
} }
static int dn_get_info(char *buffer, char **start, off_t offset, int length) static char *dn_state2asc(unsigned char state)
{ {
struct sock *sk; switch(state) {
struct dn_scp *scp; case DN_O:
int len = 0; return "OPEN";
off_t pos = 0; case DN_CR:
off_t begin = 0; return " CR";
case DN_DR:
return " DR";
case DN_DRC:
return " DRC";
case DN_CC:
return " CC";
case DN_CI:
return " CI";
case DN_NR:
return " NR";
case DN_NC:
return " NC";
case DN_CD:
return " CD";
case DN_RJ:
return " RJ";
case DN_RUN:
return " RUN";
case DN_DI:
return " DI";
case DN_DIC:
return " DIC";
case DN_DN:
return " DN";
case DN_CL:
return " CL";
case DN_CN:
return " CN";
}
return "????";
}
static inline void dn_socket_format_entry(struct seq_file *seq, struct sock *sk)
{
struct dn_scp *scp = DN_SK(sk);
char buf1[DN_ASCBUF_LEN]; char buf1[DN_ASCBUF_LEN];
char buf2[DN_ASCBUF_LEN]; char buf2[DN_ASCBUF_LEN];
char local_object[DN_MAXOBJL+3]; char local_object[DN_MAXOBJL+3];
char remote_object[DN_MAXOBJL+3]; char remote_object[DN_MAXOBJL+3];
int i;
len += sprintf(buffer + len, "Local Remote\n"); dn_printable_object(&scp->addr, local_object);
dn_printable_object(&scp->peer, remote_object);
seq_printf(seq,
"%6s/%04X %04d:%04d %04d:%04d %01d %-16s "
"%6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1),
scp->addrloc,
scp->numdat,
scp->numoth,
scp->ackxmt_dat,
scp->ackxmt_oth,
scp->flowloc_sw,
local_object,
dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2),
scp->addrrem,
scp->numdat_rcv,
scp->numoth_rcv,
scp->ackrcv_dat,
scp->ackrcv_oth,
scp->flowrem_sw,
remote_object,
dn_state2asc(scp->state),
((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
}
read_lock(&dn_hash_lock); static int dn_socket_seq_show(struct seq_file *seq, void *v)
for(i = 0; i < DN_SK_HASH_SIZE; i++) { {
for(sk = dn_sk_hash[i]; sk != NULL; sk = sk->next) { if (v == (void*)1) {
scp = DN_SK(sk); seq_puts(seq, "Local Remote\n");
} else {
dn_printable_object(&scp->addr, local_object); dn_socket_format_entry(seq, v);
dn_printable_object(&scp->peer, remote_object);
len += sprintf(buffer + len,
"%6s/%04X %04d:%04d %04d:%04d %01d %-16s %6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1),
scp->addrloc,
scp->numdat,
scp->numoth,
scp->ackxmt_dat,
scp->ackxmt_oth,
scp->flowloc_sw,
local_object,
dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2),
scp->addrrem,
scp->numdat_rcv,
scp->numoth_rcv,
scp->ackrcv_dat,
scp->ackrcv_oth,
scp->flowrem_sw,
remote_object,
dn_state2asc(scp->state),
((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > (offset + length))
break;
}
} }
read_unlock(&dn_hash_lock); return 0;
}
*start = buffer + (offset - begin); static struct seq_operations dn_socket_seq_ops = {
len -= (offset - begin); .start = dn_socket_seq_start,
.next = dn_socket_seq_next,
.stop = dn_socket_seq_stop,
.show = dn_socket_seq_show,
};
if (len > length) static int dn_socket_seq_open(struct inode *inode, struct file *file)
len = length; {
struct seq_file *seq;
int rc = -ENOMEM;
struct dn_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
return len; if (!s)
goto out;
rc = seq_open(file, &dn_socket_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
kfree(s);
goto out;
} }
static struct file_operations dn_socket_seq_fops = {
.open = dn_socket_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_private,
};
#endif
static struct net_proto_family dn_family_ops = { static struct net_proto_family dn_family_ops = {
.family = AF_DECnet, .family = AF_DECnet,
...@@ -2258,13 +2367,11 @@ static struct proto_ops dn_proto_ops = { ...@@ -2258,13 +2367,11 @@ static struct proto_ops dn_proto_ops = {
void dn_register_sysctl(void); void dn_register_sysctl(void);
void dn_unregister_sysctl(void); void dn_unregister_sysctl(void);
MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); MODULE_DESCRIPTION("The Linux DECnet Network Protocol");
MODULE_AUTHOR("Linux DECnet Project Team"); MODULE_AUTHOR("Linux DECnet Project Team");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.67s (C) 1995-2003 Linux DECnet Project Team\n";
static int __init decnet_init(void) static int __init decnet_init(void)
{ {
...@@ -2281,15 +2388,12 @@ static int __init decnet_init(void) ...@@ -2281,15 +2388,12 @@ static int __init decnet_init(void)
dev_add_pack(&dn_dix_packet_type); dev_add_pack(&dn_dix_packet_type);
register_netdevice_notifier(&dn_dev_notifier); register_netdevice_notifier(&dn_dev_notifier);
proc_net_create("decnet", 0, dn_get_info); proc_net_fops_create("decnet", S_IRUGO, &dn_socket_seq_fops);
dn_neigh_init(); dn_neigh_init();
dn_dev_init(); dn_dev_init();
dn_route_init(); dn_route_init();
#ifdef CONFIG_DECNET_ROUTER
dn_fib_init(); dn_fib_init();
#endif /* CONFIG_DECNET_ROUTER */
dn_register_sysctl(); dn_register_sysctl();
...@@ -2316,10 +2420,7 @@ static void __exit decnet_exit(void) ...@@ -2316,10 +2420,7 @@ static void __exit decnet_exit(void)
dn_route_cleanup(); dn_route_cleanup();
dn_dev_cleanup(); dn_dev_cleanup();
dn_neigh_cleanup(); dn_neigh_cleanup();
#ifdef CONFIG_DECNET_ROUTER
dn_fib_cleanup(); dn_fib_cleanup();
#endif /* CONFIG_DECNET_ROUTER */
proc_net_remove("decnet"); proc_net_remove("decnet");
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
* Steve Whitehouse : /proc/sys/net/decnet/conf/<sys>/forwarding * Steve Whitehouse : /proc/sys/net/decnet/conf/<sys>/forwarding
* Steve Whitehouse : Removed timer1 - it's a user space issue now * Steve Whitehouse : Removed timer1 - it's a user space issue now
* Patrick Caulfield : Fixed router hello message format * Patrick Caulfield : Fixed router hello message format
* Steve Whitehouse : Got rid of constant sizes for blksize for
* devices. All mtu based now.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -28,6 +30,7 @@ ...@@ -28,6 +30,7 @@
#include <linux/net.h> #include <linux/net.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
...@@ -72,16 +75,13 @@ static void rtmsg_ifa(int event, struct dn_ifaddr *ifa); ...@@ -72,16 +75,13 @@ static void rtmsg_ifa(int event, struct dn_ifaddr *ifa);
static int dn_eth_up(struct net_device *); static int dn_eth_up(struct net_device *);
static void dn_eth_down(struct net_device *); static void dn_eth_down(struct net_device *);
static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa); static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa);
#if 0
static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa); static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa);
#endif
static struct dn_dev_parms dn_dev_list[] = { static struct dn_dev_parms dn_dev_list[] = {
{ {
.type = ARPHRD_ETHER, /* Ethernet */ .type = ARPHRD_ETHER, /* Ethernet */
.mode = DN_DEV_BCAST, .mode = DN_DEV_BCAST,
.state = DN_DEV_S_RU, .state = DN_DEV_S_RU,
.blksize = 1498,
.t2 = 1, .t2 = 1,
.t3 = 10, .t3 = 10,
.name = "ethernet", .name = "ethernet",
...@@ -94,7 +94,6 @@ static struct dn_dev_parms dn_dev_list[] = { ...@@ -94,7 +94,6 @@ static struct dn_dev_parms dn_dev_list[] = {
.type = ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */ .type = ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */
.mode = DN_DEV_BCAST, .mode = DN_DEV_BCAST,
.state = DN_DEV_S_RU, .state = DN_DEV_S_RU,
.blksize = 1400,
.t2 = 1, .t2 = 1,
.t3 = 10, .t3 = 10,
.name = "ipgre", .name = "ipgre",
...@@ -106,7 +105,6 @@ static struct dn_dev_parms dn_dev_list[] = { ...@@ -106,7 +105,6 @@ static struct dn_dev_parms dn_dev_list[] = {
.type = ARPHRD_X25, /* Bog standard X.25 */ .type = ARPHRD_X25, /* Bog standard X.25 */
.mode = DN_DEV_UCAST, .mode = DN_DEV_UCAST,
.state = DN_DEV_S_DS, .state = DN_DEV_S_DS,
.blksize = 230,
.t2 = 1, .t2 = 1,
.t3 = 120, .t3 = 120,
.name = "x25", .name = "x25",
...@@ -119,7 +117,6 @@ static struct dn_dev_parms dn_dev_list[] = { ...@@ -119,7 +117,6 @@ static struct dn_dev_parms dn_dev_list[] = {
.type = ARPHRD_PPP, /* DECnet over PPP */ .type = ARPHRD_PPP, /* DECnet over PPP */
.mode = DN_DEV_BCAST, .mode = DN_DEV_BCAST,
.state = DN_DEV_S_RU, .state = DN_DEV_S_RU,
.blksize = 230,
.t2 = 1, .t2 = 1,
.t3 = 10, .t3 = 10,
.name = "ppp", .name = "ppp",
...@@ -127,24 +124,20 @@ static struct dn_dev_parms dn_dev_list[] = { ...@@ -127,24 +124,20 @@ static struct dn_dev_parms dn_dev_list[] = {
.timer3 = dn_send_brd_hello, .timer3 = dn_send_brd_hello,
}, },
#endif #endif
#if 0
{ {
.type = ARPHRD_DDCMP, /* DECnet over DDCMP */ .type = ARPHRD_DDCMP, /* DECnet over DDCMP */
.mode = DN_DEV_UCAST, .mode = DN_DEV_UCAST,
.state = DN_DEV_S_DS, .state = DN_DEV_S_DS,
.blksize = 230,
.t2 = 1, .t2 = 1,
.t3 = 120, .t3 = 120,
.name = "ddcmp", .name = "ddcmp",
.ctl_name = NET_DECNET_CONF_DDCMP, .ctl_name = NET_DECNET_CONF_DDCMP,
.timer3 = dn_send_ptp_hello, .timer3 = dn_send_ptp_hello,
}, },
#endif
{ {
.type = ARPHRD_LOOPBACK, /* Loopback interface - always last */ .type = ARPHRD_LOOPBACK, /* Loopback interface - always last */
.mode = DN_DEV_BCAST, .mode = DN_DEV_BCAST,
.state = DN_DEV_S_RU, .state = DN_DEV_S_RU,
.blksize = 1498,
.t2 = 1, .t2 = 1,
.t3 = 10, .t3 = 10,
.name = "loopback", .name = "loopback",
...@@ -254,6 +247,21 @@ static struct dn_dev_sysctl_table { ...@@ -254,6 +247,21 @@ static struct dn_dev_sysctl_table {
}, {0}} }, {0}}
}; };
static inline __u16 mtu2blksize(struct net_device *dev)
{
u32 blksize = dev->mtu;
if (blksize > 0xffff)
blksize = 0xffff;
if (dev->type == ARPHRD_ETHER ||
dev->type == ARPHRD_PPP ||
dev->type == ARPHRD_IPGRE ||
dev->type == ARPHRD_LOOPBACK)
blksize -= 2;
return (__u16)blksize;
}
static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms) static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
{ {
struct dn_dev_sysctl_table *t; struct dn_dev_sysctl_table *t;
...@@ -858,7 +866,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa) ...@@ -858,7 +866,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa)
memcpy(msg->tiver, dn_eco_version, 3); memcpy(msg->tiver, dn_eco_version, 3);
dn_dn2eth(msg->id, ifa->ifa_local); dn_dn2eth(msg->id, ifa->ifa_local);
msg->iinfo = DN_RT_INFO_ENDN; msg->iinfo = DN_RT_INFO_ENDN;
msg->blksize = dn_htons(dn_db->parms.blksize); msg->blksize = dn_htons(mtu2blksize(dev));
msg->area = 0x00; msg->area = 0x00;
memset(msg->seed, 0, 8); memset(msg->seed, 0, 8);
memcpy(msg->neighbor, dn_hiord, ETH_ALEN); memcpy(msg->neighbor, dn_hiord, ETH_ALEN);
...@@ -920,10 +928,10 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) ...@@ -920,10 +928,10 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
unsigned short *pktlen; unsigned short *pktlen;
char *src; char *src;
if (dn_db->parms.blksize < (26 + 7)) if (mtu2blksize(dev) < (26 + 7))
return; return;
n = dn_db->parms.blksize - 26; n = mtu2blksize(dev) - 26;
n /= 7; n /= 7;
if (n > 32) if (n > 32)
...@@ -946,7 +954,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) ...@@ -946,7 +954,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
ptr += ETH_ALEN; ptr += ETH_ALEN;
*ptr++ = dn_db->parms.forwarding == 1 ? *ptr++ = dn_db->parms.forwarding == 1 ?
DN_RT_INFO_L1RT : DN_RT_INFO_L2RT; DN_RT_INFO_L1RT : DN_RT_INFO_L2RT;
*((unsigned short *)ptr) = dn_htons(dn_db->parms.blksize); *((unsigned short *)ptr) = dn_htons(mtu2blksize(dev));
ptr += 2; ptr += 2;
*ptr++ = dn_db->parms.priority; /* Priority */ *ptr++ = dn_db->parms.priority; /* Priority */
*ptr++ = 0; /* Area: Reserved */ *ptr++ = 0; /* Area: Reserved */
...@@ -990,16 +998,13 @@ static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) ...@@ -990,16 +998,13 @@ static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa)
dn_send_router_hello(dev, ifa); dn_send_router_hello(dev, ifa);
} }
#if 0
static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa) static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
{ {
int tdlen = 16; int tdlen = 16;
int size = dev->hard_header_len + 2 + 4 + tdlen; int size = dev->hard_header_len + 2 + 4 + tdlen;
struct sk_buff *skb = dn_alloc_skb(NULL, size, GFP_ATOMIC); struct sk_buff *skb = dn_alloc_skb(NULL, size, GFP_ATOMIC);
struct dn_dev *dn_db = dev->dn_ptr;
int i; int i;
unsigned char *ptr; unsigned char *ptr;
struct dn_neigh *dn = (struct dn_neigh *)dn_db->router;
char src[ETH_ALEN]; char src[ETH_ALEN];
if (skb == NULL) if (skb == NULL)
...@@ -1020,7 +1025,6 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa) ...@@ -1020,7 +1025,6 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
dn_dn2eth(src, ifa->ifa_local); dn_dn2eth(src, ifa->ifa_local);
dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src); dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src);
} }
#endif
static int dn_eth_up(struct net_device *dev) static int dn_eth_up(struct net_device *dev)
{ {
...@@ -1332,6 +1336,63 @@ int dnet_gifconf(struct net_device *dev, char *buf, int len) ...@@ -1332,6 +1336,63 @@ int dnet_gifconf(struct net_device *dev, char *buf, int len)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static inline struct net_device *dn_dev_get_next(struct seq_file *seq, struct net_device *dev)
{
do {
dev = dev->next;
} while(dev && !dev->dn_ptr);
return dev;
}
static struct net_device *dn_dev_get_idx(struct seq_file *seq, loff_t pos)
{
struct net_device *dev;
dev = dev_base;
if (dev && !dev->dn_ptr)
dev = dn_dev_get_next(seq, dev);
if (pos) {
while(dev && (dev = dn_dev_get_next(seq, dev)))
--pos;
}
return dev;
}
static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
{
if (*pos) {
struct net_device *dev;
read_lock(&dev_base_lock);
dev = dn_dev_get_idx(seq, *pos - 1);
if (dev == NULL)
read_unlock(&dev_base_lock);
return dev;
}
return (void*)1;
}
static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net_device *dev = v;
loff_t one = 1;
if (v == (void*)1) {
dev = dn_dev_seq_start(seq, &one);
} else {
dev = dn_dev_get_next(seq, dev);
if (dev == NULL)
read_unlock(&dev_base_lock);
}
++*pos;
return dev;
}
static void dn_dev_seq_stop(struct seq_file *seq, void *v)
{
if (v && v != (void*)1)
read_unlock(&dev_base_lock);
}
static char *dn_type2asc(char type) static char *dn_type2asc(char type)
{ {
...@@ -1347,56 +1408,50 @@ static char *dn_type2asc(char type) ...@@ -1347,56 +1408,50 @@ static char *dn_type2asc(char type)
return "?"; return "?";
} }
static int decnet_dev_get_info(char *buffer, char **start, off_t offset, int length) static int dn_dev_seq_show(struct seq_file *seq, void *v)
{ {
struct dn_dev *dn_db; if (v == (void*)1)
struct net_device *dev; seq_puts(seq, "Name Flags T1 Timer1 T3 Timer3 BlkSize Pri State DevType Router Peer\n");
int len = 0; else {
off_t pos = 0; struct net_device *dev = v;
off_t begin = 0; char peer_buf[DN_ASCBUF_LEN];
char peer_buf[DN_ASCBUF_LEN]; char router_buf[DN_ASCBUF_LEN];
char router_buf[DN_ASCBUF_LEN]; struct dn_dev *dn_db = dev->dn_ptr;
seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu"
len += sprintf(buffer, "Name Flags T1 Timer1 T3 Timer3 BlkSize Pri State DevType Router Peer\n"); " %04hu %03d %02x %-10s %-7s %-7s\n",
read_lock(&dev_base_lock);
for (dev = dev_base; dev; dev = dev->next) {
if ((dn_db = (struct dn_dev *)dev->dn_ptr) == NULL)
continue;
len += sprintf(buffer + len, "%-8s %1s %04u %04u %04lu %04lu %04hu %03d %02x %-10s %-7s %-7s\n",
dev->name ? dev->name : "???", dev->name ? dev->name : "???",
dn_type2asc(dn_db->parms.mode), dn_type2asc(dn_db->parms.mode),
0, 0, 0, 0,
dn_db->t3, dn_db->parms.t3, dn_db->t3, dn_db->parms.t3,
dn_db->parms.blksize, mtu2blksize(dev),
dn_db->parms.priority, dn_db->parms.priority,
dn_db->parms.state, dn_db->parms.name, dn_db->parms.state, dn_db->parms.name,
dn_db->router ? dn_addr2asc(dn_ntohs(*(dn_address *)dn_db->router->primary_key), router_buf) : "", dn_db->router ? dn_addr2asc(dn_ntohs(*(dn_address *)dn_db->router->primary_key), router_buf) : "",
dn_db->peer ? dn_addr2asc(dn_ntohs(*(dn_address *)dn_db->peer->primary_key), peer_buf) : ""); dn_db->peer ? dn_addr2asc(dn_ntohs(*(dn_address *)dn_db->peer->primary_key), peer_buf) : "");
}
return 0;
}
static struct seq_operations dn_dev_seq_ops = {
.start = dn_dev_seq_start,
.next = dn_dev_seq_next,
.stop = dn_dev_seq_stop,
.show = dn_dev_seq_show,
};
pos = begin + len; static int dn_dev_seq_open(struct inode *inode, struct file *file)
{
if (pos < offset) { return seq_open(file, &dn_dev_seq_ops);
len = 0;
begin = pos;
}
if (pos > offset + length)
break;
}
read_unlock(&dev_base_lock);
*start = buffer + (offset - begin);
len -= (offset - begin);
if (len > length) len = length;
return(len);
} }
static struct file_operations dn_dev_seq_fops = {
.open = dn_dev_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] = static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
...@@ -1448,9 +1503,7 @@ void __init dn_dev_init(void) ...@@ -1448,9 +1503,7 @@ void __init dn_dev_init(void)
rtnetlink_links[PF_DECnet] = dnet_rtnetlink_table; rtnetlink_links[PF_DECnet] = dnet_rtnetlink_table;
#ifdef CONFIG_PROC_FS proc_net_fops_create("decnet_dev", S_IRUGO, &dn_dev_seq_fops);
proc_net_create("decnet_dev", 0, decnet_dev_get_info);
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
{ {
......
...@@ -67,18 +67,18 @@ static struct ...@@ -67,18 +67,18 @@ static struct
int error; int error;
u8 scope; u8 scope;
} dn_fib_props[RTA_MAX+1] = { } dn_fib_props[RTA_MAX+1] = {
{ .error = 0, .scope = RT_SCOPE_NOWHERE }, /* RTN_UNSPEC */ [RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE },
{ .error = 0, .scope = RT_SCOPE_UNIVERSE }, /* RTN_UNICAST */ [RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE },
{ .error = 0, .scope = RT_SCOPE_HOST }, /* RTN_LOCAL */ [RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST },
{ .error = -EINVAL, .scope = RT_SCOPE_NOWHERE }, /* RTN_BROADCAST */ [RTN_BROADCAST] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
{ .error = -EINVAL, .scope = RT_SCOPE_NOWHERE }, /* RTN_ANYCAST */ [RTN_ANYCAST] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
{ .error = -EINVAL, .scope = RT_SCOPE_NOWHERE }, /* RTN_MULTICAST */ [RTN_MULTICAST] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
{ .error = -EINVAL, .scope = RT_SCOPE_UNIVERSE }, /* RTN_BLACKHOLE */ [RTN_BLACKHOLE] = { .error = -EINVAL, .scope = RT_SCOPE_UNIVERSE },
{ .error = -EHOSTUNREACH, .scope = RT_SCOPE_UNIVERSE }, /* RTN_UNREACHABLE */ [RTN_UNREACHABLE] = { .error = -EHOSTUNREACH, .scope = RT_SCOPE_UNIVERSE },
{ .error = -EACCES, .scope = RT_SCOPE_UNIVERSE }, /* RTN_PROHIBIT */ [RTN_PROHIBIT] = { .error = -EACCES, .scope = RT_SCOPE_UNIVERSE },
{ .error = -EAGAIN, .scope = RT_SCOPE_UNIVERSE }, /* RTN_THROW */ [RTN_THROW] = { .error = -EAGAIN, .scope = RT_SCOPE_UNIVERSE },
{ .error = 0, .scope = RT_SCOPE_NOWHERE }, /* RTN_NAT */ [RTN_NAT] = { .error = 0, .scope = RT_SCOPE_NOWHERE },
{ .error = -EINVAL, .scope = RT_SCOPE_NOWHERE } /* RTN_XRESOLVE */ [RTN_XRESOLVE] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
}; };
void dn_fib_free_info(struct dn_fib_info *fi) void dn_fib_free_info(struct dn_fib_info *fi)
...@@ -792,53 +792,12 @@ void dn_fib_flush(void) ...@@ -792,53 +792,12 @@ void dn_fib_flush(void)
dn_rt_cache_flush(-1); dn_rt_cache_flush(-1);
} }
#ifdef CONFIG_PROC_FS
static int decnet_rt_get_info(char *buffer, char **start, off_t offset, int length)
{
int first = offset / 128;
char *ptr = buffer;
int count = (length + 127) / 128;
int len;
int i;
struct dn_fib_table *tb;
*start = buffer + (offset % 128);
if (--first < 0) {
sprintf(buffer, "%-127s\n", "Iface\tDest\tGW \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT");
--count;
ptr += 128;
first = 0;
}
for(i = RT_MIN_TABLE; (i <= RT_TABLE_MAX) && (count > 0); i++) {
if ((tb = dn_fib_get_table(i, 0)) != NULL) {
int n = tb->get_info(tb, ptr, first, count);
count -= n;
ptr += n * 128;
}
}
len = ptr - *start;
if (len >= length)
return length;
if (len >= 0)
return len;
return 0;
}
#endif /* CONFIG_PROC_FS */
static struct notifier_block dn_fib_dnaddr_notifier = { static struct notifier_block dn_fib_dnaddr_notifier = {
.notifier_call = dn_fib_dnaddr_event, .notifier_call = dn_fib_dnaddr_event,
}; };
void __exit dn_fib_cleanup(void) void __exit dn_fib_cleanup(void)
{ {
proc_net_remove("decnet_route");
dn_fib_table_cleanup(); dn_fib_table_cleanup();
dn_fib_rules_cleanup(); dn_fib_rules_cleanup();
...@@ -849,10 +808,6 @@ void __exit dn_fib_cleanup(void) ...@@ -849,10 +808,6 @@ void __exit dn_fib_cleanup(void)
void __init dn_fib_init(void) void __init dn_fib_init(void)
{ {
#ifdef CONFIG_PROC_FS
proc_net_create("decnet_route", 0, decnet_rt_get_info);
#endif
dn_fib_table_init(); dn_fib_table_init();
dn_fib_rules_init(); dn_fib_rules_init();
......
...@@ -202,7 +202,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb) ...@@ -202,7 +202,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
struct net_device *dev = neigh->dev; struct net_device *dev = neigh->dev;
char mac_addr[ETH_ALEN]; char mac_addr[ETH_ALEN];
dn_dn2eth(mac_addr, rt->rt_saddr); dn_dn2eth(mac_addr, rt->rt_local_src);
if (!dev->hard_header || dev->hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, mac_addr, skb->len) >= 0) if (!dev->hard_header || dev->hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, mac_addr, skb->len) >= 0)
return neigh->ops->queue_xmit(skb); return neigh->ops->queue_xmit(skb);
...@@ -692,48 +692,23 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file) ...@@ -692,48 +692,23 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file)
goto out; goto out;
} }
static int dn_seq_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = (struct seq_file *)file->private_data;
kfree(seq->private);
seq->private = NULL;
return seq_release(inode, file);
}
static struct file_operations dn_neigh_seq_fops = { static struct file_operations dn_neigh_seq_fops = {
.open = dn_neigh_seq_open, .open = dn_neigh_seq_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = dn_seq_release, .release = seq_release_private,
}; };
static int __init dn_neigh_proc_init(void)
{
int rc = 0;
struct proc_dir_entry *p = create_proc_entry("decnet_neigh", S_IRUGO, proc_net);
if (p)
p->proc_fops = &dn_neigh_seq_fops;
else
rc = -ENOMEM;
return rc;
}
#else
static int __init dn_neigh_proc_init(void)
{
return 0;
}
#endif #endif
void __init dn_neigh_init(void) void __init dn_neigh_init(void)
{ {
neigh_table_init(&dn_neigh_table); neigh_table_init(&dn_neigh_table);
proc_net_fops_create("decnet_neigh", S_IRUGO, &dn_neigh_seq_fops);
dn_neigh_proc_init();
} }
void __exit dn_neigh_cleanup(void) void __exit dn_neigh_cleanup(void)
{ {
proc_net_remove("decnet_neigh");
neigh_table_clear(&dn_neigh_table); neigh_table_clear(&dn_neigh_table);
} }
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
* Steve Whitehouse: Added backlog congestion level return codes. * Steve Whitehouse: Added backlog congestion level return codes.
* Patrick Caulfield: * Patrick Caulfield:
* Steve Whitehouse: Added flow control support (outbound) * Steve Whitehouse: Added flow control support (outbound)
* Steve Whitehouse: Prepare for nonlinear skbs
*/ */
/****************************************************************************** /******************************************************************************
...@@ -240,7 +241,7 @@ static struct sock *dn_find_listener(struct sk_buff *skb, unsigned short *reason ...@@ -240,7 +241,7 @@ static struct sock *dn_find_listener(struct sk_buff *skb, unsigned short *reason
cb->info = msg->info; cb->info = msg->info;
cb->segsize = dn_ntohs(msg->segsize); cb->segsize = dn_ntohs(msg->segsize);
if (skb->len < sizeof(*msg)) if (!pskb_may_pull(skb, sizeof(*msg)))
goto err_out; goto err_out;
skb_pull(skb, sizeof(*msg)); skb_pull(skb, sizeof(*msg));
...@@ -721,33 +722,18 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) ...@@ -721,33 +722,18 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
unsigned char *ptr = (unsigned char *)skb->data; unsigned char *ptr = (unsigned char *)skb->data;
unsigned short reason = NSP_REASON_NL; unsigned short reason = NSP_REASON_NL;
if (!pskb_may_pull(skb, 2))
goto free_out;
skb->h.raw = skb->data; skb->h.raw = skb->data;
cb->nsp_flags = *ptr++; cb->nsp_flags = *ptr++;
if (decnet_debug_level & 2) if (decnet_debug_level & 2)
printk(KERN_DEBUG "dn_nsp_rx: Message type 0x%02x\n", (int)cb->nsp_flags); printk(KERN_DEBUG "dn_nsp_rx: Message type 0x%02x\n", (int)cb->nsp_flags);
if (skb->len < 2)
goto free_out;
if (cb->nsp_flags & 0x83) if (cb->nsp_flags & 0x83)
goto free_out; goto free_out;
/*
* Returned packets...
* Swap src & dst and look up in the normal way.
*/
if (cb->rt_flags & DN_RT_F_RTS) {
unsigned short tmp = cb->dst_port;
cb->dst_port = cb->src_port;
cb->src_port = tmp;
tmp = cb->dst;
cb->dst = cb->src;
cb->src = tmp;
sk = dn_find_by_skb(skb);
goto got_it;
}
/* /*
* Filter out conninits and useless packet types * Filter out conninits and useless packet types
*/ */
...@@ -759,12 +745,14 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) ...@@ -759,12 +745,14 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
goto free_out; goto free_out;
case 0x10: case 0x10:
case 0x60: case 0x60:
if (unlikely(cb->rt_flags & DN_RT_F_RTS))
goto free_out;
sk = dn_find_listener(skb, &reason); sk = dn_find_listener(skb, &reason);
goto got_it; goto got_it;
} }
} }
if (skb->len < 3) if (!pskb_may_pull(skb, 3))
goto free_out; goto free_out;
/* /*
...@@ -777,12 +765,25 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) ...@@ -777,12 +765,25 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
/* /*
* If not a connack, grab the source address too. * If not a connack, grab the source address too.
*/ */
if (skb->len >= 5) { if (pskb_may_pull(skb, 5)) {
cb->src_port = *(unsigned short *)ptr; cb->src_port = *(unsigned short *)ptr;
ptr += 2; ptr += 2;
skb_pull(skb, 5); skb_pull(skb, 5);
} }
/*
* Returned packets...
* Swap src & dst and look up in the normal way.
*/
if (unlikely(cb->rt_flags & DN_RT_F_RTS)) {
unsigned short tmp = cb->dst_port;
cb->dst_port = cb->src_port;
cb->src_port = tmp;
tmp = cb->dst;
cb->dst = cb->src;
cb->src = tmp;
}
/* /*
* Find the socket to which this skb is destined. * Find the socket to which this skb is destined.
*/ */
...@@ -795,6 +796,15 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) ...@@ -795,6 +796,15 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
/* Reset backoff */ /* Reset backoff */
scp->nsp_rxtshift = 0; scp->nsp_rxtshift = 0;
/*
* We linearize everything except data segments here.
*/
if (cb->nsp_flags & ~0x60) {
if (unlikely(skb_is_nonlinear(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0)
goto free_out;
}
bh_lock_sock(sk); bh_lock_sock(sk);
ret = NET_RX_SUCCESS; ret = NET_RX_SUCCESS;
if (decnet_debug_level & 8) if (decnet_debug_level & 8)
...@@ -835,7 +845,10 @@ int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb) ...@@ -835,7 +845,10 @@ int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
struct dn_skb_cb *cb = DN_SKB_CB(skb); struct dn_skb_cb *cb = DN_SKB_CB(skb);
if (cb->rt_flags & DN_RT_F_RTS) { if (cb->rt_flags & DN_RT_F_RTS) {
dn_returned_conn_init(sk, skb); if (cb->nsp_flags == 0x18 || cb->nsp_flags == 0x68)
dn_returned_conn_init(sk, skb);
else
kfree_skb(skb);
return NET_RX_SUCCESS; return NET_RX_SUCCESS;
} }
......
...@@ -96,6 +96,7 @@ static void dn_nsp_send(struct sk_buff *skb) ...@@ -96,6 +96,7 @@ static void dn_nsp_send(struct sk_buff *skb)
fl.fld_src = dn_saddr2dn(&scp->addr); fl.fld_src = dn_saddr2dn(&scp->addr);
fl.fld_dst = dn_saddr2dn(&scp->peer); fl.fld_dst = dn_saddr2dn(&scp->peer);
dn_sk_ports_copy(&fl, scp); dn_sk_ports_copy(&fl, scp);
fl.proto = DNPROTO_NSP;
if (dn_route_output_sock(&sk->dst_cache, &fl, sk, 0) == 0) { if (dn_route_output_sock(&sk->dst_cache, &fl, sk, 0) == 0) {
dst = sk_dst_get(sk); dst = sk_dst_get(sk);
sk->route_caps = dst->dev->features; sk->route_caps = dst->dev->features;
...@@ -349,8 +350,7 @@ static inline unsigned char *dn_mk_common_header(struct dn_scp *scp, struct sk_b ...@@ -349,8 +350,7 @@ static inline unsigned char *dn_mk_common_header(struct dn_scp *scp, struct sk_b
{ {
unsigned char *ptr = skb_push(skb, len); unsigned char *ptr = skb_push(skb, len);
if (len < 5) BUG_ON(len < 5);
BUG();
*ptr++ = msgflag; *ptr++ = msgflag;
*((unsigned short *)ptr) = scp->addrrem; *((unsigned short *)ptr) = scp->addrrem;
...@@ -367,8 +367,7 @@ static unsigned short *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, un ...@@ -367,8 +367,7 @@ static unsigned short *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, un
unsigned short ackcrs = scp->numoth_rcv & 0x0FFF; unsigned short ackcrs = scp->numoth_rcv & 0x0FFF;
unsigned short *ptr; unsigned short *ptr;
if (hlen < 9) BUG_ON(hlen < 9);
BUG();
scp->ackxmt_dat = acknum; scp->ackxmt_dat = acknum;
scp->ackxmt_oth = ackcrs; scp->ackxmt_oth = ackcrs;
...@@ -485,8 +484,8 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff ...@@ -485,8 +484,8 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
* We don't expect to see acknowledgements for packets we * We don't expect to see acknowledgements for packets we
* haven't sent yet. * haven't sent yet.
*/ */
if (xmit_count == 0) WARN_ON(xmit_count == 0);
BUG();
/* /*
* If the packet has only been sent once, we can use it * If the packet has only been sent once, we can use it
* to calculate the RTT and also open the window a little * to calculate the RTT and also open the window a little
......
This diff is collapsed.
...@@ -744,86 +744,6 @@ static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp, ...@@ -744,86 +744,6 @@ static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp,
return err; return err;
} }
#ifdef CONFIG_PROC_FS
static unsigned dn_fib_flag_trans(int type, int dead, u16 mask, struct dn_fib_info *fi)
{
static unsigned type2flags[RTN_MAX+1] = {
0, 0, 0, 0, 0, 0, 0, RTF_REJECT, RTF_REJECT, 0, 0, 0
};
unsigned flags = type2flags[type];
if (fi && fi->fib_nh->nh_gw)
flags |= RTF_GATEWAY;
if (mask == 0xFFFF)
flags |= RTF_HOST;
if (dead)
flags |= RTF_UP;
return flags;
}
static void dn_fib_node_get_info(int type, int dead, struct dn_fib_info *fi, u16 prefix, u16 mask, char *buffer)
{
int len;
unsigned flags = dn_fib_flag_trans(type, dead, mask, fi);
if (fi) {
len = sprintf(buffer, "%s\t%04x\t%04x\t%04x\t%d\t%u\t%d\t%04x\t%d\t%u\t%u",
fi->dn_fib_dev ? fi->dn_fib_dev->name : "*", prefix,
fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority,
mask, 0, 0, 0);
} else {
len = sprintf(buffer, "*\t%04x\t%04x\t%04x\t%d\t%u\t%d\t%04x\t%d\t%u\t%u",
prefix, 0,
flags, 0, 0, 0,
mask, 0, 0, 0);
}
memset(buffer+len, ' ', 127-len);
buffer[127] = '\n';
}
static int dn_fib_table_get_info(struct dn_fib_table *tb, char *buffer, int first, int count)
{
struct dn_hash *table = (struct dn_hash *)tb->data;
struct dn_zone *dz;
int pos = 0;
int n = 0;
read_lock(&dn_fib_tables_lock);
for(dz = table->dh_zone_list; dz; dz = dz->dz_next) {
int i;
struct dn_fib_node *f;
int maxslot = dz->dz_divisor;
struct dn_fib_node **fp = dz->dz_hash;
if (dz->dz_nent == 0)
continue;
if (pos + dz->dz_nent < first) {
pos += dz->dz_nent;
continue;
}
for(i = 0; i < maxslot; i++, fp++) {
for(f = *fp; f ; f = f->fn_next) {
if (++pos <= first)
continue;
dn_fib_node_get_info(f->fn_type,
f->fn_state & DN_S_ZOMBIE,
DN_FIB_INFO(f),
dz_prefix(f->fn_key, dz),
DZ_MASK(dz), buffer);
buffer += 128;
if (++n >= count)
goto out;
}
}
}
out:
read_unlock(&dn_fib_tables_lock);
return n;
}
#endif /* CONFIG_PROC_FS */
struct dn_fib_table *dn_fib_get_table(int n, int create) struct dn_fib_table *dn_fib_get_table(int n, int create)
{ {
...@@ -855,9 +775,6 @@ struct dn_fib_table *dn_fib_get_table(int n, int create) ...@@ -855,9 +775,6 @@ struct dn_fib_table *dn_fib_get_table(int n, int create)
t->delete = dn_fib_table_delete; t->delete = dn_fib_table_delete;
t->lookup = dn_fib_table_lookup; t->lookup = dn_fib_table_lookup;
t->flush = dn_fib_table_flush; t->flush = dn_fib_table_flush;
#ifdef CONFIG_PROC_FS
t->get_info = dn_fib_table_get_info;
#endif
t->dump = dn_fib_table_dump; t->dump = dn_fib_table_dump;
memset(t->data, 0, sizeof(struct dn_hash)); memset(t->data, 0, sizeof(struct dn_hash));
dn_fib_tables[n] = t; dn_fib_tables[n] = t;
......
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