we can save container_of computation and return dst directly, since dst is always first member of struct rt6_info
Add a BUILD_BUG_ON() to catch any change that could break this assertion. Signed-off-by: Li RongQing <lirongq...@baidu.com> --- include/net/ip6_route.h | 4 +++- net/ipv6/route.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 7b9c82de11cc..1f09298634cb 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -194,8 +194,10 @@ static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) const struct dst_entry *dst = skb_dst(skb); const struct rt6_info *rt6 = NULL; + BUILD_BUG_ON(offsetof(struct rt6_info, dst) != 0); + if (dst) - rt6 = container_of(dst, struct rt6_info, dst); + rt6 = (struct rt6_info *)dst; return rt6; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d28f83e01593..3fb8034fc2d0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -217,7 +217,7 @@ static struct neighbour *ip6_dst_neigh_lookup(const struct dst_entry *dst, struct sk_buff *skb, const void *daddr) { - const struct rt6_info *rt = container_of(dst, struct rt6_info, dst); + const struct rt6_info *rt = (struct rt6_info *)dst; return ip6_neigh_lookup(&rt->rt6i_gateway, dst->dev, skb, daddr); } @@ -2187,7 +2187,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) struct fib6_info *from; struct rt6_info *rt; - rt = container_of(dst, struct rt6_info, dst); + rt = (struct rt6_info *)dst; rcu_read_lock(); @@ -4911,7 +4911,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, } - rt = container_of(dst, struct rt6_info, dst); + rt = (struct rt6_info *)dst; if (rt->dst.error) { err = rt->dst.error; ip6_rt_put(rt); -- 2.16.2