162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _NET_DST_OPS_H
362306a36Sopenharmony_ci#define _NET_DST_OPS_H
462306a36Sopenharmony_ci#include <linux/types.h>
562306a36Sopenharmony_ci#include <linux/percpu_counter.h>
662306a36Sopenharmony_ci#include <linux/cache.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_cistruct dst_entry;
962306a36Sopenharmony_cistruct kmem_cachep;
1062306a36Sopenharmony_cistruct net_device;
1162306a36Sopenharmony_cistruct sk_buff;
1262306a36Sopenharmony_cistruct sock;
1362306a36Sopenharmony_cistruct net;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct dst_ops {
1662306a36Sopenharmony_ci	unsigned short		family;
1762306a36Sopenharmony_ci	unsigned int		gc_thresh;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	void			(*gc)(struct dst_ops *ops);
2062306a36Sopenharmony_ci	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
2162306a36Sopenharmony_ci	unsigned int		(*default_advmss)(const struct dst_entry *);
2262306a36Sopenharmony_ci	unsigned int		(*mtu)(const struct dst_entry *);
2362306a36Sopenharmony_ci	u32 *			(*cow_metrics)(struct dst_entry *, unsigned long);
2462306a36Sopenharmony_ci	void			(*destroy)(struct dst_entry *);
2562306a36Sopenharmony_ci	void			(*ifdown)(struct dst_entry *,
2662306a36Sopenharmony_ci					  struct net_device *dev);
2762306a36Sopenharmony_ci	struct dst_entry *	(*negative_advice)(struct dst_entry *);
2862306a36Sopenharmony_ci	void			(*link_failure)(struct sk_buff *);
2962306a36Sopenharmony_ci	void			(*update_pmtu)(struct dst_entry *dst, struct sock *sk,
3062306a36Sopenharmony_ci					       struct sk_buff *skb, u32 mtu,
3162306a36Sopenharmony_ci					       bool confirm_neigh);
3262306a36Sopenharmony_ci	void			(*redirect)(struct dst_entry *dst, struct sock *sk,
3362306a36Sopenharmony_ci					    struct sk_buff *skb);
3462306a36Sopenharmony_ci	int			(*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb);
3562306a36Sopenharmony_ci	struct neighbour *	(*neigh_lookup)(const struct dst_entry *dst,
3662306a36Sopenharmony_ci						struct sk_buff *skb,
3762306a36Sopenharmony_ci						const void *daddr);
3862306a36Sopenharmony_ci	void			(*confirm_neigh)(const struct dst_entry *dst,
3962306a36Sopenharmony_ci						 const void *daddr);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	struct kmem_cache	*kmem_cachep;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	struct percpu_counter	pcpuc_entries ____cacheline_aligned_in_smp;
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic inline int dst_entries_get_fast(struct dst_ops *dst)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	return percpu_counter_read_positive(&dst->pcpuc_entries);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic inline int dst_entries_get_slow(struct dst_ops *dst)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	return percpu_counter_sum_positive(&dst->pcpuc_entries);
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define DST_PERCPU_COUNTER_BATCH 32
5762306a36Sopenharmony_cistatic inline void dst_entries_add(struct dst_ops *dst, int val)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	percpu_counter_add_batch(&dst->pcpuc_entries, val,
6062306a36Sopenharmony_ci				 DST_PERCPU_COUNTER_BATCH);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic inline int dst_entries_init(struct dst_ops *dst)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	return percpu_counter_init(&dst->pcpuc_entries, 0, GFP_KERNEL);
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistatic inline void dst_entries_destroy(struct dst_ops *dst)
6962306a36Sopenharmony_ci{
7062306a36Sopenharmony_ci	percpu_counter_destroy(&dst->pcpuc_entries);
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#endif
74