Commit d6667fe4 authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji

[IPV6]: Store idev in routes.

parent 20e743bb
......@@ -57,6 +57,8 @@ struct rt6_info
struct rt6_info *next;
} u;
struct inet6_dev *rt6i_idev;
#define rt6i_dev u.dst.dev
#define rt6i_nexthop u.dst.neighbour
#define rt6i_expires u.dst.expires
......
......@@ -83,6 +83,7 @@ static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static void ip6_dst_destroy(struct dst_entry *);
static int ip6_dst_gc(void);
static int ip6_pkt_discard(struct sk_buff *skb);
......@@ -95,6 +96,7 @@ static struct dst_ops ip6_dst_ops = {
.gc = ip6_dst_gc,
.gc_thresh = 1024,
.check = ip6_dst_check,
.destroy = ip6_dst_destroy,
.negative_advice = ip6_negative_advice,
.link_failure = ip6_link_failure,
.update_pmtu = ip6_rt_update_pmtu,
......@@ -134,7 +136,15 @@ rwlock_t rt6_lock = RW_LOCK_UNLOCKED;
/* allocate dst with ip6_dst_ops */
static __inline__ struct rt6_info *ip6_dst_alloc(void)
{
return dst_alloc(&ip6_dst_ops);
return (struct rt6_info *)dst_alloc(&ip6_dst_ops);
}
static void ip6_dst_destroy(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *)dst;
if (rt->rt6i_idev != NULL)
in6_dev_put(rt->rt6i_idev);
}
/*
......@@ -581,6 +591,7 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
neigh = ndisc_get_neigh(dev, addr);
rt->rt6i_dev = dev;
rt->rt6i_idev = dev ? in6_dev_get(dev) : NULL;
rt->rt6i_nexthop = neigh;
rt->rt6i_expires = 0;
rt->rt6i_flags = RTF_LOCAL;
......@@ -714,6 +725,12 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
if (rtmsg->rtmsg_src_len)
return -EINVAL;
#endif
if (rtmsg->rtmsg_ifindex) {
dev = dev_get_by_index(rtmsg->rtmsg_ifindex);
if (!dev)
return -ENODEV;
}
if (rtmsg->rtmsg_metric == 0)
rtmsg->rtmsg_metric = IP6_RT_PRIO_USER;
......@@ -739,13 +756,6 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
rt->u.dst.output = ip6_output;
if (rtmsg->rtmsg_ifindex) {
dev = dev_get_by_index(rtmsg->rtmsg_ifindex);
err = -ENODEV;
if (dev == NULL)
goto out;
}
ipv6_addr_prefix(&rt->rt6i_dst.addr,
&rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len);
rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len;
......@@ -872,6 +882,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
if (!rt->u.dst.metrics[RTAX_ADVMSS-1])
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
rt->u.dst.dev = dev;
rt->rt6i_idev = in6_dev_get(dev);
return rt6_ins(rt, nlh, _rtattr);
out:
......@@ -1138,6 +1149,9 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
rt->u.dst.dev = ort->u.dst.dev;
if (rt->u.dst.dev)
dev_hold(rt->u.dst.dev);
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
rt->u.dst.lastuse = jiffies;
rt->rt6i_expires = 0;
......@@ -1282,6 +1296,7 @@ int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev, int anycast)
rt->u.dst.input = ip6_input;
rt->u.dst.output = ip6_output;
rt->rt6i_dev = &loopback_dev;
rt->rt6i_idev = in6_dev_get(&loopback_dev);
rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ipv6_get_hoplimit(rt->rt6i_dev);
......
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