cregit-Linux how code gets into the kernel

Release 4.14 net/core/dst_cache.c

Directory: net/core
/*
 * net/core/dst_cache.c - dst entry cache
 *
 * Copyright (c) 2016 Paolo Abeni <pabeni@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/percpu.h>
#include <net/dst_cache.h>
#include <net/route.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ip6_fib.h>
#endif
#include <uapi/linux/in.h>


struct dst_cache_pcpu {
	
unsigned long refresh_ts;
	
struct dst_entry *dst;
	
u32 cookie;
	union {
		
struct in_addr in_saddr;
		
struct in6_addr in6_saddr;
	};
};


static void dst_cache_per_cpu_dst_set(struct dst_cache_pcpu *dst_cache, struct dst_entry *dst, u32 cookie) { dst_release(dst_cache->dst); if (dst) dst_hold(dst); dst_cache->cookie = cookie; dst_cache->dst = dst; }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni4697.87%150.00%
Fengguang Wu12.13%150.00%
Total47100.00%2100.00%


static struct dst_entry *dst_cache_per_cpu_get(struct dst_cache *dst_cache, struct dst_cache_pcpu *idst) { struct dst_entry *dst; dst = idst->dst; if (!dst) goto fail; /* the cache already hold a dst reference; it can't go away */ dst_hold(dst); if (unlikely(!time_after(idst->refresh_ts, dst_cache->reset_ts) || (dst->obsolete && !dst->ops->check(dst, idst->cookie)))) { dst_cache_per_cpu_dst_set(idst, NULL, 0); dst_release(dst); goto fail; } return dst; fail: idst->refresh_ts = jiffies; return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni11299.12%150.00%
Fengguang Wu10.88%150.00%
Total113100.00%2100.00%


struct dst_entry *dst_cache_get(struct dst_cache *dst_cache) { if (!dst_cache->cache) return NULL; return dst_cache_per_cpu_get(dst_cache, this_cpu_ptr(dst_cache->cache)); }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni35100.00%1100.00%
Total35100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_get);
struct rtable *dst_cache_get_ip4(struct dst_cache *dst_cache, __be32 *saddr) { struct dst_cache_pcpu *idst; struct dst_entry *dst; if (!dst_cache->cache) return NULL; idst = this_cpu_ptr(dst_cache->cache); dst = dst_cache_per_cpu_get(dst_cache, idst); if (!dst) return NULL; *saddr = idst->in_saddr.s_addr; return container_of(dst, struct rtable, dst); }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni82100.00%1100.00%
Total82100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_get_ip4);
void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst, __be32 saddr) { struct dst_cache_pcpu *idst; if (!dst_cache->cache) return; idst = this_cpu_ptr(dst_cache->cache); dst_cache_per_cpu_dst_set(idst, dst, 0); idst->in_saddr.s_addr = saddr; }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni57100.00%1100.00%
Total57100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_set_ip4); #if IS_ENABLED(CONFIG_IPV6)
void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, const struct in6_addr *addr) { struct dst_cache_pcpu *idst; if (!dst_cache->cache) return; idst = this_cpu_ptr(dst_cache->cache); dst_cache_per_cpu_dst_set(this_cpu_ptr(dst_cache->cache), dst, rt6_get_cookie((struct rt6_info *)dst)); idst->in6_saddr = *addr; }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni72100.00%1100.00%
Total72100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_set_ip6);
struct dst_entry *dst_cache_get_ip6(struct dst_cache *dst_cache, struct in6_addr *saddr) { struct dst_cache_pcpu *idst; struct dst_entry *dst; if (!dst_cache->cache) return NULL; idst = this_cpu_ptr(dst_cache->cache); dst = dst_cache_per_cpu_get(dst_cache, idst); if (!dst) return NULL; *saddr = idst->in6_saddr; return dst; }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni73100.00%1100.00%
Total73100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_get_ip6); #endif
int dst_cache_init(struct dst_cache *dst_cache, gfp_t gfp) { dst_cache->cache = alloc_percpu_gfp(struct dst_cache_pcpu, gfp | __GFP_ZERO); if (!dst_cache->cache) return -ENOMEM; dst_cache_reset(dst_cache); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni46100.00%1100.00%
Total46100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_init);
void dst_cache_destroy(struct dst_cache *dst_cache) { int i; if (!dst_cache->cache) return; for_each_possible_cpu(i) dst_release(per_cpu_ptr(dst_cache->cache, i)->dst); free_percpu(dst_cache->cache); }

Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni46100.00%1100.00%
Total46100.00%1100.00%

EXPORT_SYMBOL_GPL(dst_cache_destroy);

Overall Contributors

PersonTokensPropCommitsCommitProp
Paolo Abeni66899.70%150.00%
Fengguang Wu20.30%150.00%
Total670100.00%2100.00%
Directory: net/core
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.