From d6667fe4ad63731210b60d71101720c60acc8c41 Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Mon, 31 May 2004 22:27:14 -0700 Subject: [PATCH] [IPV6]: Store idev in routes. --- include/net/ip6_fib.h | 2 ++ net/ipv6/route.c | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index d0ca2230a34fc..14d41c4baa991 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -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 diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 03863849e868c..b3d52015e82b6 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -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 @@ install_route: 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); -- 2.53.0