static struct dst_entry *tunnel_dst_check(struct ip_tunnel *t, u32 cookie) { struct dst_entry *dst = tunnel_dst_get(t); if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { tunnel_dst_reset(t); return NULL; } return dst; }
static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) { struct dst_entry *dst; rcu_read_lock(); dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst); if (dst) { if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) { rcu_read_unlock(); tunnel_dst_reset(t); return NULL; } dst_hold(dst); } rcu_read_unlock(); return (struct rtable *)dst; }
static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) { struct dst_entry *dst; rcu_read_lock(); dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst); if (dst && !atomic_inc_not_zero(&dst->__refcnt)) dst = NULL; if (dst) { if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) { tunnel_dst_reset(t); dst_release(dst); dst = NULL; } } rcu_read_unlock(); return (struct rtable *)dst; }
static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie, __be32 *saddr) { struct ip_tunnel_dst *idst; struct dst_entry *dst; rcu_read_lock(); idst = raw_cpu_ptr(t->dst_cache); dst = rcu_dereference(idst->dst); if (dst && !atomic_inc_not_zero(&dst->__refcnt)) dst = NULL; if (dst) { if (!dst->obsolete || dst->ops->check(dst, cookie)) { *saddr = idst->saddr; } else { tunnel_dst_reset(t); dst_release(dst); dst = NULL; } } rcu_read_unlock(); return (struct rtable *)dst; }