{
struct dn_route *chain;
spinlock_t lock;
-} __attribute__((__aligned__(8)));
+};
extern struct neigh_table dn_neigh_table;
static unsigned long dn_rt_deadline;
-static int dn_dst_gc(void);
+static int dn_dst_gc(struct dst_ops *ops);
static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
static void dn_dst_link_failure(struct sk_buff *);
mod_timer(&dn_route_timer, now + decnet_dst_gc_interval * HZ);
}
-static int dn_dst_gc(void)
+static int dn_dst_gc(struct dst_ops *ops)
{
struct dn_route *rt, **rtp;
int i;
dn_rt_hash_table[hash].chain);
rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth);
- rth->u.dst.__use++;
- dst_hold(&rth->u.dst);
- rth->u.dst.lastuse = now;
+ dst_use(&rth->u.dst, now);
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
dnrt_drop(rt);
rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain);
rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt);
- dst_hold(&rt->u.dst);
- rt->u.dst.__use++;
- rt->u.dst.lastuse = now;
+ dst_use(&rt->u.dst, now);
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
*rp = rt;
return 0;
return NET_RX_DROP;
}
-/*
- * Drop packet. This is used for endnodes and for
- * when we should not be forwarding packets from
- * this dest.
- */
-static int dn_blackhole(struct sk_buff *skb)
-{
- kfree_skb(skb);
- return NET_RX_DROP;
-}
-
/*
* Used to catch bugs. This should never normally get
* called.
* here
*/
if (!try_hard) {
- neigh = neigh_lookup_nodev(&dn_neigh_table, &fl.fld_dst);
+ neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst);
if (neigh) {
if ((oldflp->oif &&
(neigh->dev->ifindex != oldflp->oif)) ||
(flp->mark == rt->fl.mark) &&
(rt->fl.iif == 0) &&
(rt->fl.oif == flp->oif)) {
- rt->u.dst.lastuse = jiffies;
- dst_hold(&rt->u.dst);
- rt->u.dst.__use++;
+ dst_use(&rt->u.dst, jiffies);
rcu_read_unlock_bh();
*pprt = &rt->u.dst;
return 0;
err = __dn_route_output_key(pprt, fl, flags & MSG_TRYHARD);
if (err == 0 && fl->proto) {
- err = xfrm_lookup(pprt, fl, sk, !(flags & MSG_DONTWAIT));
+ err = xfrm_lookup(pprt, fl, sk, (flags & MSG_DONTWAIT) ?
+ 0 : XFRM_LOOKUP_WAIT);
}
return err;
}
default:
case RTN_UNREACHABLE:
case RTN_BLACKHOLE:
- rt->u.dst.input = dn_blackhole;
+ rt->u.dst.input = dst_discard;
}
rt->rt_flags = flags;
if (rt->u.dst.dev)
(rt->fl.oif == 0) &&
(rt->fl.mark == skb->mark) &&
(rt->fl.iif == cb->iif)) {
- rt->u.dst.lastuse = jiffies;
- dst_hold(&rt->u.dst);
- rt->u.dst.__use++;
+ dst_use(&rt->u.dst, jiffies);
rcu_read_unlock();
skb->dst = (struct dst_entry *)rt;
return 0;
*/
static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
{
+ struct net *net = in_skb->sk->sk_net;
struct rtattr **rta = arg;
struct rtmsg *rtm = NLMSG_DATA(nlh);
struct dn_route *rt = NULL;
struct sk_buff *skb;
struct flowi fl;
+ if (net != &init_net)
+ return -EINVAL;
+
memset(&fl, 0, sizeof(fl));
fl.proto = DNPROTO_NSP;
kfree_skb(skb);
return -ENODEV;
}
- skb->protocol = __constant_htons(ETH_P_DNA_RT);
+ skb->protocol = htons(ETH_P_DNA_RT);
skb->dev = dev;
cb->src = fl.fld_src;
cb->dst = fl.fld_dst;
goto out_free;
}
- return rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+ return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
out_free:
kfree_skb(skb);
*/
int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
+ struct net *net = skb->sk->sk_net;
struct dn_route *rt;
int h, s_h;
int idx, s_idx;
+ if (net != &init_net)
+ return 0;
+
if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg))
return -EINVAL;
if (!(((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED))
break;
rcu_read_unlock_bh();
}
- return rt;
+ return rcu_dereference(rt);
}
static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_route *rt)
{
- struct dn_rt_cache_iter_state *s = rcu_dereference(seq->private);
+ struct dn_rt_cache_iter_state *s = seq->private;
rt = rt->u.dst.dn_next;
while(!rt) {
rcu_read_lock_bh();
rt = dn_rt_hash_table[s->bucket].chain;
}
- return rt;
+ return rcu_dereference(rt);
}
static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
static int dn_rt_cache_seq_open(struct inode *inode, struct file *file)
{
- struct seq_file *seq;
- int rc = -ENOMEM;
- struct dn_rt_cache_iter_state *s;
-
- s = kzalloc(sizeof(*s), GFP_KERNEL);
- if (!s)
- goto out;
- rc = seq_open(file, &dn_rt_cache_seq_ops);
- if (rc)
- goto out_kfree;
- seq = file->private_data;
- seq->private = s;
-out:
- return rc;
-out_kfree:
- kfree(s);
- goto out;
+ return seq_open_private(file, &dn_rt_cache_seq_ops,
+ sizeof(struct dn_rt_cache_iter_state));
}
static const struct file_operations dn_rt_cache_seq_fops = {
dn_dst_ops.kmem_cachep =
kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
- init_timer(&dn_route_timer);
- dn_route_timer.function = dn_dst_check_expire;
+ setup_timer(&dn_route_timer, dn_dst_check_expire, 0);
dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
add_timer(&dn_route_timer);