cregit-Linux how code gets into the kernel

Release 4.12 include/net/dst.h

Directory: include/net
/*
 * net/dst.h    Protocol independent destination cache definitions.
 *
 * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 */

#ifndef _NET_DST_H

#define _NET_DST_H

#include <net/dst_ops.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/rcupdate.h>
#include <linux/bug.h>
#include <linux/jiffies.h>
#include <net/neighbour.h>
#include <asm/processor.h>


#define DST_GC_MIN	(HZ/10)

#define DST_GC_INC	(HZ/2)

#define DST_GC_MAX	(120*HZ)

/* Each dst_entry has reference count and sits in some parent list(s).
 * When it is removed from parent list, it is "freed" (dst_free).
 * After this it enters dead state (dst->obsolete > 0) and if its refcnt
 * is zero, it can be destroyed immediately, otherwise it is added
 * to gc list and garbage collector periodically checks the refcnt.
 */

struct sk_buff;


struct dst_entry {
	
struct rcu_head		rcu_head;
	
struct dst_entry	*child;
	
struct net_device       *dev;
	
struct  dst_ops	        *ops;
	
unsigned long		_metrics;
	
unsigned long           expires;
	
struct dst_entry	*path;
	
struct dst_entry	*from;
#ifdef CONFIG_XFRM
	
struct xfrm_state	*xfrm;
#else
	
void			*__pad1;
#endif
	
int			(*input)(struct sk_buff *);
	
int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);

	
unsigned short		flags;

#define DST_HOST		0x0001

#define DST_NOXFRM		0x0002

#define DST_NOPOLICY		0x0004

#define DST_NOHASH		0x0008

#define DST_NOCACHE		0x0010

#define DST_NOCOUNT		0x0020

#define DST_FAKE_RTABLE		0x0040

#define DST_XFRM_TUNNEL		0x0080

#define DST_XFRM_QUEUE		0x0100

#define DST_METADATA		0x0200

	
short			error;

	/* A non-zero value of dst->obsolete forces by-hand validation
         * of the route entry.  Positive values are set by the generic
         * dst layer to indicate that the entry has been forcefully
         * destroyed.
         *
         * Negative values are used by the implementation layer code to
         * force invocation of the dst_ops->check() method.
         */
	
short			obsolete;

#define DST_OBSOLETE_NONE	0

#define DST_OBSOLETE_DEAD	2

#define DST_OBSOLETE_FORCE_CHK	-1

#define DST_OBSOLETE_KILL	-2
	
unsigned short		header_len;	/* more space at head required */
	
unsigned short		trailer_len;	/* space to reserve at tail */
	
unsigned short		__pad3;

#ifdef CONFIG_IP_ROUTE_CLASSID
	
__u32			tclassid;
#else
	
__u32			__pad2;
#endif

#ifdef CONFIG_64BIT
	/*
         * Align __refcnt to a 64 bytes alignment
         * (L1_CACHE_SIZE would be too much)
         */
	
long			__pad_to_align_refcnt[2];
#endif
	/*
         * __refcnt wants to be on a different cache line from
         * input/output/ops or performance tanks badly
         */
	
atomic_t		__refcnt;	/* client references    */
	
int			__use;
	
unsigned long		lastuse;
	
struct lwtunnel_state   *lwtstate;
	union {
		
struct dst_entry	*next;
		
struct rtable __rcu	*rt_next;
		
struct rt6_info		*rt6_next;
		
struct dn_route __rcu	*dn_next;
	};
};


struct dst_metrics {
	
u32		metrics[RTAX_MAX];
	
atomic_t	refcnt;
};
extern const struct dst_metrics dst_default_metrics;

u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);


#define DST_METRICS_READ_ONLY		0x1UL

#define DST_METRICS_REFCOUNTED		0x2UL

#define DST_METRICS_FLAGS		0x3UL

#define __DST_METRICS_PTR(Y)	\
	((u32 *)((Y) & ~DST_METRICS_FLAGS))

#define DST_METRICS_PTR(X)	__DST_METRICS_PTR((X)->_metrics)


static inline bool dst_metrics_read_only(const struct dst_entry *dst) { return dst->_metrics & DST_METRICS_READ_ONLY; }

Contributors

PersonTokensPropCommitsCommitProp
Alexey Kuznetsov1470.00%125.00%
David S. Miller525.00%250.00%
Stephen Hemminger15.00%125.00%
Total20100.00%4100.00%

void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old);
static inline void dst_destroy_metrics_generic(struct dst_entry *dst) { unsigned long val = dst->_metrics; if (!(val & DST_METRICS_READ_ONLY)) __dst_destroy_metrics_generic(dst, val); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller2877.78%266.67%
Alexey Kuznetsov822.22%133.33%
Total36100.00%3100.00%


static inline u32 *dst_metrics_write_ptr(struct dst_entry *dst) { unsigned long p = dst->_metrics; BUG_ON(!p); if (p & DST_METRICS_READ_ONLY) return dst->ops->cow_metrics(dst, p); return __DST_METRICS_PTR(p); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller4486.27%250.00%
Stephen Hemminger611.76%125.00%
Alexey Kuznetsov11.96%125.00%
Total51100.00%4100.00%

/* This may only be invoked before the entry has reached global * visibility. */
static inline void dst_init_metrics(struct dst_entry *dst, const u32 *src_metrics, bool read_only) { dst->_metrics = ((unsigned long) src_metrics) | (read_only ? DST_METRICS_READ_ONLY : 0); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller40100.00%2100.00%
Total40100.00%2100.00%


static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src) { u32 *dst_metrics = dst_metrics_write_ptr(dest); if (dst_metrics) { u32 *src_metrics = DST_METRICS_PTR(src); memcpy(dst_metrics, src_metrics, RTAX_MAX * sizeof(u32)); } }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller56100.00%2100.00%
Total56100.00%2100.00%


static inline u32 *dst_metrics_ptr(struct dst_entry *dst) { return DST_METRICS_PTR(dst); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller19100.00%2100.00%
Total19100.00%2100.00%


static inline u32 dst_metric_raw(const struct dst_entry *dst, const int metric) { u32 *p = DST_METRICS_PTR(dst); return p[metric-1]; }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller34100.00%2100.00%
Total34100.00%2100.00%


static inline u32 dst_metric(const struct dst_entry *dst, const int metric) { WARN_ON_ONCE(metric == RTAX_HOPLIMIT || metric == RTAX_ADVMSS || metric == RTAX_MTU); return dst_metric_raw(dst, metric); }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller40100.00%2100.00%
Total40100.00%2100.00%


static inline u32 dst_metric_advmss(const struct dst_entry *dst) { u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS); if (!advmss) advmss = dst->ops->default_advmss(dst); return advmss; }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller4095.24%266.67%
Alexey Kuznetsov24.76%133.33%
Total42100.00%3100.00%


static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { u32 *p = dst_metrics_write_ptr(dst); if (p) p[metric-1] = val; }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller40100.00%1100.00%
Total40100.00%1100.00%

/* Kernel-internal feature bits that are unallocated in user space. */ #define DST_FEATURE_ECN_CA (1 << 31) #define DST_FEATURE_MASK (DST_FEATURE_ECN_CA) #define DST_FEATURE_ECN_MASK (DST_FEATURE_ECN_CA | RTAX_FEATURE_ECN)
static inline u32 dst_feature(const struct dst_entry *dst, u32 feature) { return dst_metric(dst, RTAX_FEATURES) & feature; }

Contributors

PersonTokensPropCommitsCommitProp
Gilad Ben-Yossef26100.00%1100.00%
Total26100.00%1100.00%


static inline u32 dst_mtu(const struct dst_entry *dst) { return dst->ops->mtu(dst); }

Contributors

PersonTokensPropCommitsCommitProp
Herbert Xu1460.87%125.00%
David S. Miller730.43%125.00%
Steffen Klassert28.70%250.00%
Total23100.00%4100.00%

/* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */
static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metric) { return msecs_to_jiffies(dst_metric(dst, metric)); }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Hemminger28100.00%1100.00%
Total28100.00%1100.00%


static inline u32 dst_allfrag(const struct dst_entry *dst) { int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Hideaki Yoshifuji / 吉藤英明2284.62%133.33%
Alexey Kuznetsov27.69%133.33%
Gilad Ben-Yossef27.69%133.33%
Total26100.00%3100.00%


static inline int dst_metric_locked(const struct dst_entry *dst, int metric) { return dst_metric(dst, RTAX_LOCK) & (1<<metric); }

Contributors

PersonTokensPropCommitsCommitProp
Alexey Kuznetsov2790.00%133.33%
Hideaki Yoshifuji / 吉藤英明26.67%133.33%
David S. Miller13.33%133.33%
Total30100.00%3100.00%


static inline void dst_hold(struct dst_entry *dst) { /* * If your kernel compilation stops here, please check * __pad_to_align_refcnt declaration in struct dst_entry */ BUILD_BUG_ON(offsetof(struct dst_entry, __refcnt) & 63); atomic_inc(&dst->__refcnt); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2058.82%480.00%
Eric Dumazet1441.18%120.00%
Total34100.00%5100.00%


static inline void dst_use(struct dst_entry *dst, unsigned long time) { dst_hold(dst); dst->__use++; dst->lastuse = time; }

Contributors

PersonTokensPropCommitsCommitProp
Pavel Emelyanov32100.00%1100.00%
Total32100.00%1100.00%


static inline void dst_use_noref(struct dst_entry *dst, unsigned long time) { dst->__use++; dst->lastuse = time; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet27100.00%1100.00%
Total27100.00%1100.00%


static inline struct dst_entry *dst_clone(struct dst_entry *dst) { if (dst) atomic_inc(&dst->__refcnt); return dst; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)29100.00%4100.00%
Total29100.00%4100.00%

void dst_release(struct dst_entry *dst);
static inline void refdst_drop(unsigned long refdst) { if (!(refdst & SKB_DST_NOREF)) dst_release((struct dst_entry *)(refdst & SKB_DST_PTRMASK)); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet34100.00%1100.00%
Total34100.00%1100.00%

/** * skb_dst_drop - drops skb dst * @skb: buffer * * Drops dst reference count if a reference was taken. */
static inline void skb_dst_drop(struct sk_buff *skb) { if (skb->_skb_refdst) { refdst_drop(skb->_skb_refdst); skb->_skb_refdst = 0UL; } }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet33100.00%2100.00%
Total33100.00%2100.00%


static inline void __skb_dst_copy(struct sk_buff *nskb, unsigned long refdst) { nskb->_skb_refdst = refdst; if (!(nskb->_skb_refdst & SKB_DST_NOREF)) dst_clone(skb_dst(nskb)); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet3687.80%266.67%
Joe Stringer512.20%133.33%
Total41100.00%3100.00%


static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb) { __skb_dst_copy(nskb, oskb->_skb_refdst); }

Contributors

PersonTokensPropCommitsCommitProp
Joe Stringer27100.00%1100.00%
Total27100.00%1100.00%

/** * skb_dst_force - makes sure skb dst is refcounted * @skb: buffer * * If dst is not yet refcounted, let's do it */
static inline void skb_dst_force(struct sk_buff *skb) { if (skb_dst_is_noref(skb)) { WARN_ON(!rcu_read_lock_held()); skb->_skb_refdst &= ~SKB_DST_NOREF; dst_clone(skb_dst(skb)); } }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet43100.00%2100.00%
Total43100.00%2100.00%

/** * dst_hold_safe - Take a reference on a dst if possible * @dst: pointer to dst entry * * This helper returns false if it could not safely * take a reference on a dst. */
static inline bool dst_hold_safe(struct dst_entry *dst) { if (dst->flags & DST_NOCACHE) return atomic_inc_not_zero(&dst->__refcnt); dst_hold(dst); return true; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet37100.00%1100.00%
Total37100.00%1100.00%

/** * skb_dst_force_safe - makes sure skb dst is refcounted * @skb: buffer * * If dst is not yet refcounted and not destroyed, grab a ref on it. */
static inline void skb_dst_force_safe(struct sk_buff *skb) { if (skb_dst_is_noref(skb)) { struct dst_entry *dst = skb_dst(skb); if (!dst_hold_safe(dst)) dst = NULL; skb->_skb_refdst = (unsigned long)dst; } }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet53100.00%1100.00%
Total53100.00%1100.00%

/** * __skb_tunnel_rx - prepare skb for rx reinsert * @skb: buffer * @dev: tunnel device * @net: netns for packet i/o * * After decapsulation, packet is going to re-enter (netif_rx()) our stack, * so make some cleanups. (no accounting done) */
static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev, struct net *net) { skb->dev = dev; /* * Clear hash so that we can recalulate the hash for the * encapsulated packet, unless we have already determine the hash * over the L4 4-tuple. */ skb_clear_hash_if_not_l4(skb); skb_set_queue_mapping(skb, 0); skb_scrub_packet(skb, !net_eq(net, dev_net(dev))); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet3052.63%240.00%
Nicolas Dichtel1628.07%120.00%
Tom Herbert1119.30%240.00%
Total57100.00%5100.00%

/** * skb_tunnel_rx - prepare skb for rx reinsert * @skb: buffer * @dev: tunnel device * * After decapsulation, packet is going to re-enter (netif_rx()) our stack, * so make some cleanups, and perform accounting. * Note: this accounting is not SMP safe. */
static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev, struct net *net) { /* TODO : stats should be SMP safe */ dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; __skb_tunnel_rx(skb, dev, net); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet4285.71%150.00%
Nicolas Dichtel714.29%150.00%
Total49100.00%2100.00%


static inline u32 dst_tclassid(const struct sk_buff *skb) { #ifdef CONFIG_IP_ROUTE_CLASSID const struct dst_entry *dst; dst = skb_dst(skb); if (dst) return dst->tclassid; #endif return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Borkmann43100.00%1100.00%
Total43100.00%1100.00%

int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
static inline int dst_discard(struct sk_buff *skb) { return dst_discard_out(&init_net, skb->sk, skb); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet2184.00%150.00%
Eric W. Biedermann416.00%150.00%
Total25100.00%2100.00%

void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, int initial_obsolete, unsigned short flags); void dst_init(struct dst_entry *dst, struct dst_ops *ops, struct net_device *dev, int initial_ref, int initial_obsolete, unsigned short flags); void __dst_free(struct dst_entry *dst); struct dst_entry *dst_destroy(struct dst_entry *dst);
static inline void dst_free(struct dst_entry *dst) { if (dst->obsolete > 0) return; if (!atomic_read(&dst->__refcnt)) { dst = dst_destroy(dst); if (!dst) return; } __dst_free(dst); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)4484.62%571.43%
Alexey Kuznetsov713.46%114.29%
David S. Miller11.92%114.29%
Total52100.00%7100.00%


static inline void dst_rcu_free(struct rcu_head *head) { struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head); dst_free(dst); }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton32100.00%1100.00%
Total32100.00%1100.00%


static inline void dst_confirm(struct dst_entry *dst) { }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)1090.91%266.67%
Julian Anastasov19.09%133.33%
Total11100.00%3100.00%


static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr) { struct neighbour *n = dst->ops->neigh_lookup(dst, NULL, daddr); return IS_ERR(n) ? NULL : n; }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller3368.75%266.67%
Zhouyi Zhou1531.25%133.33%
Total48100.00%3100.00%


static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst, struct sk_buff *skb) { struct neighbour *n = dst->ops->neigh_lookup(dst, skb, NULL); return IS_ERR(n) ? NULL : n; }

Contributors

PersonTokensPropCommitsCommitProp
David S. Miller3368.75%150.00%
Zhouyi Zhou1531.25%150.00%
Total48100.00%2100.00%


static inline void dst_confirm_neigh(const struct dst_entry *dst, const void *daddr) { if (dst->ops->confirm_neigh) dst->ops->confirm_neigh(dst, daddr); }

Contributors

PersonTokensPropCommitsCommitProp
Julian Anastasov37100.00%1100.00%
Total37100.00%1100.00%


static inline void dst_link_failure(struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); if (dst && dst->ops && dst->ops->link_failure) dst->ops->link_failure(skb); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)4293.33%266.67%
Eric Dumazet36.67%133.33%
Total45100.00%3100.00%


static inline void dst_set_expires(struct dst_entry *dst, int timeout) { unsigned long expires = jiffies + timeout; if (expires == 0) expires = 1; if (dst->expires == 0 || time_before(expires, dst->expires)) dst->expires = expires; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)5394.64%266.67%
David S. Miller35.36%133.33%
Total56100.00%3100.00%

/* Output packet to network from transport. */
static inline int dst_output(struct net *net, struct sock *sk, struct sk_buff *skb) { return skb_dst(skb)->output(net, sk, skb); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet1437.84%228.57%
Alexey Kuznetsov1437.84%114.29%
Eric W. Biedermann821.62%342.86%
Patrick McHardy12.70%114.29%
Total37100.00%7100.00%

/* Input packet from network to transport. */
static inline int dst_input(struct sk_buff *skb) { return skb_dst(skb)->input(skb); }

Contributors

PersonTokensPropCommitsCommitProp
Alexey Kuznetsov1982.61%133.33%
Eric Dumazet313.04%133.33%
David S. Miller14.35%133.33%
Total23100.00%3100.00%


static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie) { if (dst->obsolete) dst = dst->ops->check(dst, cookie); return dst; }

Contributors

PersonTokensPropCommitsCommitProp
Herbert Xu39100.00%1100.00%
Total39100.00%1100.00%

void dst_subsys_init(void); /* Flags for xfrm_lookup flags argument. */ enum { XFRM_LOOKUP_ICMP = 1 << 0, XFRM_LOOKUP_QUEUE = 1 << 1, XFRM_LOOKUP_KEEP_DST_REF = 1 << 2, }; struct flowi; #ifndef CONFIG_XFRM
static inline struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, const struct flowi *fl, const struct sock *sk, int flags) { return dst_orig; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen2567.57%120.00%
David S. Miller616.22%240.00%
Alexey Dobriyan513.51%120.00%
Eric Dumazet12.70%120.00%
Total37100.00%5100.00%


static inline struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, const struct flowi *fl, const struct sock *sk, int flags) { return dst_orig; }

Contributors

PersonTokensPropCommitsCommitProp
Steffen Klassert3697.30%150.00%
Eric Dumazet12.70%150.00%
Total37100.00%2100.00%


static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) { return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Vlad Yasevich18100.00%1100.00%
Total18100.00%1100.00%

#else struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, const struct flowi *fl, const struct sock *sk, int flags); struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, const struct flowi *fl, const struct sock *sk, int flags); /* skb attached with this dst needs transformation if dst->xfrm is valid */
static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) { return dst->xfrm; }

Contributors

PersonTokensPropCommitsCommitProp
Vlad Yasevich20100.00%1100.00%
Total20100.00%1100.00%

#endif #endif /* _NET_DST_H */

Overall Contributors

PersonTokensPropCommitsCommitProp
David S. Miller56825.76%1918.81%
Eric Dumazet49122.27%1413.86%
Linus Torvalds (pre-git)30914.01%1413.86%
Alexey Kuznetsov1366.17%32.97%
Steffen Klassert773.49%54.95%
Herbert Xu703.17%54.95%
Daniel Borkmann562.54%21.98%
Julian Anastasov421.90%21.98%
Vlad Yasevich391.77%10.99%
Stephen Hemminger361.63%32.97%
Thomas Graf341.54%10.99%
Andrew Morton321.45%10.99%
Joe Stringer321.45%10.99%
Pavel Emelyanov321.45%10.99%
Zhouyi Zhou301.36%10.99%
Andi Kleen301.36%10.99%
Gilad Ben-Yossef281.27%10.99%
Hideaki Yoshifuji / 吉藤英明271.22%21.98%
Nicolas Dichtel241.09%10.99%
Eric W. Biedermann231.04%32.97%
Alexey Dobriyan180.82%32.97%
Yanmin Zhang160.73%10.99%
Tom Herbert110.50%21.98%
Jiri Benc70.32%21.98%
Huaibin Wang60.27%10.99%
Dipankar Sarma50.23%10.99%
Michal Kubeček50.23%10.99%
Linus Torvalds30.14%10.99%
Gao Feng30.14%10.99%
Hannes Frederic Sowa30.14%10.99%
Arnaldo Carvalho de Melo30.14%10.99%
Peter Huang (Peng)30.14%10.99%
Paul Gortmaker30.14%10.99%
Patrick McHardy20.09%21.98%
Ilpo Järvinen10.05%10.99%
Eldad Zack0.00%00.00%
Total2205100.00%101100.00%
Directory: include/net
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.