#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/netlink.h>
#include <linux/hash.h>
#include <linux/nospec.h>
#include <net/arp.h>
#include <net/inet_dscp.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/route.h>
#include <net/tcp.h>
#include <net/sock.h>
#include <net/ip_fib.h>
#include <net/ip6_fib.h>
#include <net/nexthop.h>
#include <net/netlink.h>
#include <net/rtnh.h>
#include <net/lwtunnel.h>
#include <net/fib_notifier.h>
#include <net/addrconf.h>
#include "fib_lookup.h"
static DEFINE_SPINLOCK(fib_info_lock);
static struct hlist_head *fib_info_hash;
static struct hlist_head *fib_info_laddrhash;
static unsigned int fib_info_hash_size;
static unsigned int fib_info_hash_bits;
static unsigned int fib_info_cnt;
#define DEVINDEX_HASHBITS …
#define DEVINDEX_HASHSIZE …
static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
#ifdef CONFIG_IP_ROUTE_MULTIPATH
#define for_nexthops(fi) …
#define change_nexthops(fi) …
#else
#define for_nexthops …
#define change_nexthops …
#endif
#define endfor_nexthops(fi) …
const struct fib_prop fib_props[RTN_MAX + 1] = …;
static void rt_fibinfo_free(struct rtable __rcu **rtp)
{ … }
static void free_nh_exceptions(struct fib_nh_common *nhc)
{ … }
static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp)
{ … }
void fib_nh_common_release(struct fib_nh_common *nhc)
{ … }
EXPORT_SYMBOL_GPL(…);
void fib_nh_release(struct net *net, struct fib_nh *fib_nh)
{ … }
static void free_fib_info_rcu(struct rcu_head *head)
{ … }
void free_fib_info(struct fib_info *fi)
{ … }
EXPORT_SYMBOL_GPL(…);
void fib_release_info(struct fib_info *fi)
{ … }
static inline int nh_comp(struct fib_info *fi, struct fib_info *ofi)
{ … }
static inline unsigned int fib_devindex_hashfn(unsigned int val)
{ … }
static struct hlist_head *
fib_info_devhash_bucket(const struct net_device *dev)
{ … }
static unsigned int fib_info_hashfn_1(int init_val, u8 protocol, u8 scope,
u32 prefsrc, u32 priority)
{ … }
static unsigned int fib_info_hashfn_result(unsigned int val)
{ … }
static inline unsigned int fib_info_hashfn(struct fib_info *fi)
{ … }
static struct fib_info *fib_find_info_nh(struct net *net,
const struct fib_config *cfg)
{ … }
static struct fib_info *fib_find_info(struct fib_info *nfi)
{ … }
int ip_fib_check_default(__be32 gw, struct net_device *dev)
{ … }
size_t fib_nlmsg_size(struct fib_info *fi)
{ … }
void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
int dst_len, u32 tb_id, const struct nl_info *info,
unsigned int nlm_flags)
{ … }
static int fib_detect_death(struct fib_info *fi, int order,
struct fib_info **last_resort, int *last_idx,
int dflt)
{ … }
int fib_nh_common_init(struct net *net, struct fib_nh_common *nhc,
struct nlattr *encap, u16 encap_type,
void *cfg, gfp_t gfp_flags,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
int fib_nh_init(struct net *net, struct fib_nh *nh,
struct fib_config *cfg, int nh_weight,
struct netlink_ext_ack *extack)
{ … }
#ifdef CONFIG_IP_ROUTE_MULTIPATH
static int fib_count_nexthops(struct rtnexthop *rtnh, int remaining,
struct netlink_ext_ack *extack)
{ … }
static int fib_gw_from_attr(__be32 *gw, struct nlattr *nla,
struct netlink_ext_ack *extack)
{ … }
static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
int remaining, struct fib_config *cfg,
struct netlink_ext_ack *extack)
{ … }
static void fib_rebalance(struct fib_info *fi)
{ … }
#else
static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
int remaining, struct fib_config *cfg,
struct netlink_ext_ack *extack)
{
NL_SET_ERR_MSG(extack, "Multipath support not enabled in kernel");
return -EINVAL;
}
#define fib_rebalance …
#endif
static int fib_encap_match(struct net *net, u16 encap_type,
struct nlattr *encap,
const struct fib_nh *nh,
const struct fib_config *cfg,
struct netlink_ext_ack *extack)
{ … }
int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi,
struct netlink_ext_ack *extack)
{ … }
bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi)
{ … }
static int fib_check_nh_v6_gw(struct net *net, struct fib_nh *nh,
u32 table, struct netlink_ext_ack *extack)
{ … }
static int fib_check_nh_v4_gw(struct net *net, struct fib_nh *nh, u32 table,
u8 scope, struct netlink_ext_ack *extack)
{ … }
static int fib_check_nh_nongw(struct net *net, struct fib_nh *nh,
struct netlink_ext_ack *extack)
{ … }
int fib_check_nh(struct net *net, struct fib_nh *nh, u32 table, u8 scope,
struct netlink_ext_ack *extack)
{ … }
static struct hlist_head *
fib_info_laddrhash_bucket(const struct net *net, __be32 val)
{ … }
static void fib_info_hash_move(struct hlist_head *new_info_hash,
struct hlist_head *new_laddrhash,
unsigned int new_size)
{ … }
__be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
unsigned char scope)
{ … }
__be32 fib_result_prefsrc(struct net *net, struct fib_result *res)
{ … }
static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
{ … }
struct fib_info *fib_create_info(struct fib_config *cfg,
struct netlink_ext_ack *extack)
{ … }
int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nhc,
u8 rt_family, unsigned char *flags, bool skip_oif)
{ … }
EXPORT_SYMBOL_GPL(…);
#if IS_ENABLED(CONFIG_IP_ROUTE_MULTIPATH) || IS_ENABLED(CONFIG_IPV6)
int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nhc,
int nh_weight, u8 rt_family, u32 nh_tclassid)
{ … }
EXPORT_SYMBOL_GPL(…);
#endif
#ifdef CONFIG_IP_ROUTE_MULTIPATH
static int fib_add_multipath(struct sk_buff *skb, struct fib_info *fi)
{ … }
#else
static int fib_add_multipath(struct sk_buff *skb, struct fib_info *fi)
{
return 0;
}
#endif
int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
const struct fib_rt_info *fri, unsigned int flags)
{ … }
int fib_sync_down_addr(struct net_device *dev, __be32 local)
{ … }
static int call_fib_nh_notifiers(struct fib_nh *nh,
enum fib_event_type event_type)
{ … }
void fib_nhc_update_mtu(struct fib_nh_common *nhc, u32 new, u32 orig)
{ … }
void fib_sync_mtu(struct net_device *dev, u32 orig_mtu)
{ … }
int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
{ … }
static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
{ … }
int fib_sync_up(struct net_device *dev, unsigned char nh_flags)
{ … }
#ifdef CONFIG_IP_ROUTE_MULTIPATH
static bool fib_good_nh(const struct fib_nh *nh)
{ … }
void fib_select_multipath(struct fib_result *res, int hash)
{ … }
#endif
void fib_select_path(struct net *net, struct fib_result *res,
struct flowi4 *fl4, const struct sk_buff *skb)
{ … }