#include <linux/rcupdate.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/cache.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/tcp.h>
#include <linux/hash.h>
#include <linux/tcp_metrics.h>
#include <linux/vmalloc.h>
#include <net/inet_connection_sock.h>
#include <net/net_namespace.h>
#include <net/request_sock.h>
#include <net/inetpeer.h>
#include <net/sock.h>
#include <net/ipv6.h>
#include <net/dst.h>
#include <net/tcp.h>
#include <net/genetlink.h>
static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *saddr,
const struct inetpeer_addr *daddr,
struct net *net, unsigned int hash);
struct tcp_fastopen_metrics { … };
#define TCP_METRIC_MAX_KERNEL …
struct tcp_metrics_block { … };
static inline struct net *tm_net(const struct tcp_metrics_block *tm)
{ … }
static bool tcp_metric_locked(struct tcp_metrics_block *tm,
enum tcp_metric_index idx)
{ … }
static u32 tcp_metric_get(const struct tcp_metrics_block *tm,
enum tcp_metric_index idx)
{ … }
static void tcp_metric_set(struct tcp_metrics_block *tm,
enum tcp_metric_index idx,
u32 val)
{ … }
static bool addr_same(const struct inetpeer_addr *a,
const struct inetpeer_addr *b)
{ … }
struct tcpm_hash_bucket { … };
static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly;
static unsigned int tcp_metrics_hash_log __read_mostly;
static DEFINE_SPINLOCK(tcp_metrics_lock);
static DEFINE_SEQLOCK(fastopen_seqlock);
static void tcpm_suck_dst(struct tcp_metrics_block *tm,
const struct dst_entry *dst,
bool fastopen_clear)
{ … }
#define TCP_METRICS_TIMEOUT …
static void tcpm_check_stamp(struct tcp_metrics_block *tm,
const struct dst_entry *dst)
{ … }
#define TCP_METRICS_RECLAIM_DEPTH …
#define TCP_METRICS_RECLAIM_PTR …
#define deref_locked(p) …
static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
struct inetpeer_addr *saddr,
struct inetpeer_addr *daddr,
unsigned int hash)
{ … }
static struct tcp_metrics_block *tcp_get_encode(struct tcp_metrics_block *tm, int depth)
{ … }
static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *saddr,
const struct inetpeer_addr *daddr,
struct net *net, unsigned int hash)
{ … }
static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
struct dst_entry *dst)
{ … }
static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk,
struct dst_entry *dst,
bool create)
{ … }
void tcp_update_metrics(struct sock *sk)
{ … }
void tcp_init_metrics(struct sock *sk)
{ … }
bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst)
{ … }
void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
struct tcp_fastopen_cookie *cookie)
{ … }
void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
struct tcp_fastopen_cookie *cookie, bool syn_lost,
u16 try_exp)
{ … }
static struct genl_family tcp_metrics_nl_family;
static const struct nla_policy tcp_metrics_nl_policy[TCP_METRICS_ATTR_MAX + 1] = …;
static int tcp_metrics_fill_info(struct sk_buff *msg,
struct tcp_metrics_block *tm)
{ … }
static int tcp_metrics_dump_info(struct sk_buff *skb,
struct netlink_callback *cb,
struct tcp_metrics_block *tm)
{ … }
static int tcp_metrics_nl_dump(struct sk_buff *skb,
struct netlink_callback *cb)
{ … }
static int __parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
unsigned int *hash, int optional, int v4, int v6)
{ … }
static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
unsigned int *hash, int optional)
{ … }
static int parse_nl_saddr(struct genl_info *info, struct inetpeer_addr *addr)
{ … }
static int tcp_metrics_nl_cmd_get(struct sk_buff *skb, struct genl_info *info)
{ … }
static void tcp_metrics_flush_all(struct net *net)
{ … }
static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
{ … }
static const struct genl_small_ops tcp_metrics_nl_ops[] = …;
static struct genl_family tcp_metrics_nl_family __ro_after_init = …;
static unsigned int tcpmhash_entries __initdata;
static int __init set_tcpmhash_entries(char *str)
{ … }
__setup(…);
static void __init tcp_metrics_hash_alloc(void)
{ … }
static void __net_exit tcp_net_metrics_exit_batch(struct list_head *net_exit_list)
{ … }
static __net_initdata struct pernet_operations tcp_net_metrics_ops = …;
void __init tcp_metrics_init(void)
{ … }