diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
commit | d6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch) | |
tree | e2be02f33984c48ec019c654051d27964e42c441 /net/decnet/dn_fib.c | |
parent | 609d1e803baf519487233b765eb487f9ec227a18 (diff) |
Merge with 2.3.19.
Diffstat (limited to 'net/decnet/dn_fib.c')
-rw-r--r-- | net/decnet/dn_fib.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 1e9de20f2..e34f4b6aa 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -9,6 +9,7 @@ * * * Changes: + * Alexey Kuznetsov : SMP locking changes * */ #include <linux/config.h> @@ -23,7 +24,7 @@ #include <linux/proc_fs.h> #include <linux/netdevice.h> #include <linux/timer.h> -#include <asm/spinlock.h> +#include <linux/spinlock.h> #include <asm/atomic.h> #include <asm/uaccess.h> #include <net/neighbour.h> @@ -46,6 +47,7 @@ #ifdef CONFIG_RTNETLINK static int dn_fib_table_dump(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb); static void dn_rtmsg_fib(int event, int table, struct dn_fib_action *fa, struct nlmsghdr *nlh, struct netlink_skb_parms *req); +extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb); #endif /* CONFIG_RTNETLINK */ static void dn_fib_del_tree(struct dn_fib_table *t); @@ -448,7 +450,7 @@ int dn_fib_resolve(struct dn_fib_res *res) struct dn_fib_table *t = dn_fib_get_tree(table, 0); if (t == NULL) - return -ENOBUFS; + return -ENOENT; if ((err = t->lookup(t, res)) < 0) return err; @@ -465,7 +467,13 @@ int dn_fib_resolve(struct dn_fib_res *res) return -ENOENT; } - return (fa->fa_type == RTN_PROHIBIT) ? -fa->fa_error : 0; + switch(fa->fa_type) { + case RTN_PROHIBIT: + case RTN_UNREACHABLE: + return -fa->fa_error; + } + + return 0; } /* @@ -487,9 +495,9 @@ static int dn_fib_convert_rtm(struct dn_fib_action *fa, struct netlink_skb_parms *req) { dn_address dst, gw, mask = 0xffff; - int ifindex; + int ifindex = 0; struct neighbour *neigh; - struct device *dev; + struct net_device *dev; unsigned char addr[ETH_ALEN]; if (r->rtm_family != AF_DECnet) @@ -505,16 +513,16 @@ static int dn_fib_convert_rtm(struct dn_fib_action *fa, memcpy(&gw, RTA_DATA(rta[RTA_GATEWAY-1]), 2); fa->fa_key = dn_ntohs(dst); - fa->fa_mask = mask; + fa->fa_mask = dn_ntohs(mask); fa->fa_ifindex = ifindex; fa->fa_proto = r->rtm_protocol; fa->fa_type = r->rtm_type; switch(fa->fa_type) { case RTN_UNICAST: - if ((dev = dev_get_by_index(ifindex)) == NULL) + if ((dev = __dev_get_by_index(ifindex)) == NULL) return -ENODEV; - dn_dn2eth(addr, gw); + dn_dn2eth(addr, dn_ntohs(gw)); if ((neigh = __neigh_lookup(&dn_neigh_table, &addr, dev, 1)) == NULL) return -EHOSTUNREACH; fa->fa_neigh = neigh; @@ -523,11 +531,14 @@ static int dn_fib_convert_rtm(struct dn_fib_action *fa, fa->fa_table = 0; break; case RTN_PROHIBIT: - fa->fa_error = 0; + fa->fa_error = EPERM; break; case RTN_UNREACHABLE: fa->fa_error = EHOSTUNREACH; break; + case RTN_BLACKHOLE: + fa->fa_error = EINVAL; + break; } return 0; @@ -662,20 +673,31 @@ static int dn_fib_table_dump(struct dn_fib_table *t, struct sk_buff *skb, struct int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) { + int t; int s_t; - struct dn_fib_table *t; + struct dn_fib_table *tb; + + if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) && + ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED) + return dn_cache_dump(skb, cb); + + s_t = cb->args[0]; + if (s_t == 0) + s_t = cb->args[0] = DN_MIN_TABLE; - for(s_t = cb->args[0]; s_t < DN_NUM_TABLES; s_t++) { - if (s_t > cb->args[0]) + for(t = s_t; t < DN_NUM_TABLES; t++) { + if (t < s_t) + continue; + if (t > s_t) memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int)); - t = dn_fib_get_tree(s_t, 0); - if (t == NULL) + tb = dn_fib_get_tree(t, 0); + if (tb == NULL) continue; - if (t->dump(t, skb, cb) < 0) + if (tb->dump(tb, skb, cb) < 0) break; } - cb->args[0] = s_t; + cb->args[0] = t; return skb->len; } @@ -696,6 +718,8 @@ int dn_fib_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return -EINVAL; } +#ifdef CONFIG_PROC_FS + struct dn_fib_procfs { int len; off_t pos; @@ -781,6 +805,8 @@ static struct proc_dir_entry proc_net_decnet_route = { decnet_rt_get_info }; +#endif /* CONFIG_PROC_FS */ + #ifdef CONFIG_DECNET_MODULE void dn_fib_cleanup(void) { |