Commit d6667fe4 authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji

[IPV6]: Store idev in routes.

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