linux/include/net/ip6_fib.h

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *	Linux INET6 implementation 
 *
 *	Authors:
 *	Pedro Roque		<[email protected]>	
 */

#ifndef _IP6_FIB_H
#define _IP6_FIB_H

#include <linux/ipv6_route.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <net/dst.h>
#include <net/flow.h>
#include <net/ip_fib.h>
#include <net/netlink.h>
#include <net/inetpeer.h>
#include <net/fib_notifier.h>
#include <linux/indirect_call_wrapper.h>
#include <uapi/linux/bpf.h>

#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB6_TABLE_HASHSZ
#else
#define FIB6_TABLE_HASHSZ
#endif

#define RT6_DEBUG

struct rt6_info;
struct fib6_info;

struct fib6_config {};

struct fib6_node {};

struct fib6_gc_args {};

#ifndef CONFIG_IPV6_SUBTREES
#define FIB6_SUBTREE

static inline bool fib6_routes_require_src(const struct net *net)
{
	return false;
}

static inline void fib6_routes_require_src_inc(struct net *net) {}
static inline void fib6_routes_require_src_dec(struct net *net) {}

#else

static inline bool fib6_routes_require_src(const struct net *net)
{}

static inline void fib6_routes_require_src_inc(struct net *net)
{}

static inline void fib6_routes_require_src_dec(struct net *net)
{}

#define FIB6_SUBTREE(fn)
#endif

/*
 *	routing information
 *
 */

struct rt6key {};

struct fib6_table;

struct rt6_exception_bucket {};

struct rt6_exception {};

#define FIB6_EXCEPTION_BUCKET_SIZE_SHIFT
#define FIB6_EXCEPTION_BUCKET_SIZE
#define FIB6_MAX_DEPTH

struct fib6_nh {};

struct fib6_info {};

struct rt6_info {};

struct fib6_result {};

#define for_each_fib6_node_rt_rcu(fn)

#define for_each_fib6_walker_rt(w)

#define dst_rt6_info(_ptr)

static inline struct inet6_dev *ip6_dst_idev(const struct dst_entry *dst)
{}

static inline bool fib6_requires_src(const struct fib6_info *rt)
{}

/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever
 * been added to a table before.
 */
static inline void fib6_clean_expires(struct fib6_info *f6i)
{}

/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever
 * been added to a table before.
 */
static inline void fib6_set_expires(struct fib6_info *f6i,
				    unsigned long expires)
{}

static inline bool fib6_check_expired(const struct fib6_info *f6i)
{}

/* Function to safely get fn->fn_sernum for passed in rt
 * and store result in passed in cookie.
 * Return true if we can get cookie safely
 * Return false if not
 */
static inline bool fib6_get_cookie_safe(const struct fib6_info *f6i,
					u32 *cookie)
{}

static inline u32 rt6_get_cookie(const struct rt6_info *rt)
{}

static inline void ip6_rt_put(struct rt6_info *rt)
{}

struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh);
void fib6_info_destroy_rcu(struct rcu_head *head);

static inline void fib6_info_hold(struct fib6_info *f6i)
{}

static inline bool fib6_info_hold_safe(struct fib6_info *f6i)
{}

static inline void fib6_info_release(struct fib6_info *f6i)
{}

enum fib6_walk_state {};

struct fib6_walker {};

struct rt6_statistics {};

#define RTN_TL_ROOT
#define RTN_ROOT
#define RTN_RTINFO

/*
 *	priority levels (or metrics)
 *
 */


struct fib6_table {};

#define RT6_TABLE_UNSPEC
#define RT6_TABLE_MAIN
#define RT6_TABLE_DFLT
#define RT6_TABLE_INFO
#define RT6_TABLE_PREFIX

#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB6_TABLE_MIN
#define FIB6_TABLE_MAX
#define RT6_TABLE_LOCAL
#else
#define FIB6_TABLE_MIN
#define FIB6_TABLE_MAX
#define RT6_TABLE_LOCAL
#endif

pol_lookup_t;

struct fib6_entry_notifier_info {};

/*
 *	exported functions
 */

struct fib6_table *fib6_get_table(struct net *net, u32 id);
struct fib6_table *fib6_new_table(struct net *net, u32 id);
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
				   const struct sk_buff *skb,
				   int flags, pol_lookup_t lookup);

/* called with rcu lock held; can return error pointer
 * caller needs to select path
 */
int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
		struct fib6_result *res, int flags);

/* called with rcu lock held; caller needs to select path */
int fib6_table_lookup(struct net *net, struct fib6_table *table,
		      int oif, struct flowi6 *fl6, struct fib6_result *res,
		      int strict);

void fib6_select_path(const struct net *net, struct fib6_result *res,
		      struct flowi6 *fl6, int oif, bool have_oif_match,
		      const struct sk_buff *skb, int strict);
struct fib6_node *fib6_node_lookup(struct fib6_node *root,
				   const struct in6_addr *daddr,
				   const struct in6_addr *saddr);

struct fib6_node *fib6_locate(struct fib6_node *root,
			      const struct in6_addr *daddr, int dst_len,
			      const struct in6_addr *saddr, int src_len,
			      bool exact_match);

void fib6_clean_all(struct net *net, int (*func)(struct fib6_info *, void *arg),
		    void *arg);
void fib6_clean_all_skip_notify(struct net *net,
				int (*func)(struct fib6_info *, void *arg),
				void *arg);

int fib6_add(struct fib6_node *root, struct fib6_info *rt,
	     struct nl_info *info, struct netlink_ext_ack *extack);
int fib6_del(struct fib6_info *rt, struct nl_info *info);

static inline
void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr)
{}

int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
		 struct fib6_config *cfg, gfp_t gfp_flags,
		 struct netlink_ext_ack *extack);
void fib6_nh_release(struct fib6_nh *fib6_nh);
void fib6_nh_release_dsts(struct fib6_nh *fib6_nh);

int call_fib6_entry_notifiers(struct net *net,
			      enum fib_event_type event_type,
			      struct fib6_info *rt,
			      struct netlink_ext_ack *extack);
int call_fib6_multipath_entry_notifiers(struct net *net,
					enum fib_event_type event_type,
					struct fib6_info *rt,
					unsigned int nsiblings,
					struct netlink_ext_ack *extack);
int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt);
void fib6_rt_update(struct net *net, struct fib6_info *rt,
		    struct nl_info *info);
void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
		     unsigned int flags);

void fib6_run_gc(unsigned long expires, struct net *net, bool force);

void fib6_gc_cleanup(void);

int fib6_init(void);

/* Add the route to the gc list if it is not already there
 *
 * The callers should hold f6i->fib6_table->tb6_lock.
 */
static inline void fib6_add_gc_list(struct fib6_info *f6i)
{}

/* Remove the route from the gc list if it is on the list.
 *
 * The callers should hold f6i->fib6_table->tb6_lock.
 */
static inline void fib6_remove_gc_list(struct fib6_info *f6i)
{}

struct ipv6_route_iter {};

extern const struct seq_operations ipv6_route_seq_ops;

int call_fib6_notifier(struct notifier_block *nb,
		       enum fib_event_type event_type,
		       struct fib_notifier_info *info);
int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,
			struct fib_notifier_info *info);

int __net_init fib6_notifier_init(struct net *net);
void __net_exit fib6_notifier_exit(struct net *net);

unsigned int fib6_tables_seq_read(struct net *net);
int fib6_tables_dump(struct net *net, struct notifier_block *nb,
		     struct netlink_ext_ack *extack);

void fib6_update_sernum(struct net *net, struct fib6_info *rt);
void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt);
void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i);

void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val);
static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric)
{}
void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
			    bool offload, bool trap, bool offload_failed);

#if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL)
struct bpf_iter__ipv6_route {};
#endif

INDIRECT_CALLABLE_DECLARE();
INDIRECT_CALLABLE_DECLARE();
INDIRECT_CALLABLE_DECLARE();
INDIRECT_CALLABLE_DECLARE();
static inline struct rt6_info *pol_lookup_func(pol_lookup_t lookup,
						struct net *net,
						struct fib6_table *table,
						struct flowi6 *fl6,
						const struct sk_buff *skb,
						int flags)
{}

#ifdef CONFIG_IPV6_MULTIPLE_TABLES
static inline bool fib6_has_custom_rules(const struct net *net)
{}

int fib6_rules_init(void);
void fib6_rules_cleanup(void);
bool fib6_rule_default(const struct fib_rule *rule);
int fib6_rules_dump(struct net *net, struct notifier_block *nb,
		    struct netlink_ext_ack *extack);
unsigned int fib6_rules_seq_read(struct net *net);

static inline bool fib6_rules_early_flow_dissect(struct net *net,
						 struct sk_buff *skb,
						 struct flowi6 *fl6,
						 struct flow_keys *flkeys)
{}
#else
static inline bool fib6_has_custom_rules(const struct net *net)
{
	return false;
}
static inline int               fib6_rules_init(void)
{
	return 0;
}
static inline void              fib6_rules_cleanup(void)
{
	return ;
}
static inline bool fib6_rule_default(const struct fib_rule *rule)
{
	return true;
}
static inline int fib6_rules_dump(struct net *net, struct notifier_block *nb,
				  struct netlink_ext_ack *extack)
{
	return 0;
}
static inline unsigned int fib6_rules_seq_read(struct net *net)
{
	return 0;
}
static inline bool fib6_rules_early_flow_dissect(struct net *net,
						 struct sk_buff *skb,
						 struct flowi6 *fl6,
						 struct flow_keys *flkeys)
{
	return false;
}
#endif
#endif