^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * INET An implementation of the TCP/IP protocol suite for the LINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * operating system. INET is implemented using the BSD Socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * interface as the means of communication with the user level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Definitions for the Forwarding Information Base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Authors: A.N.Kuznetsov, <kuznet@ms2.inr.ac.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #ifndef _NET_IP_FIB_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define _NET_IP_FIB_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/flow.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/fib_notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/fib_rules.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/inetpeer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/refcount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct fib_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u8 fc_dst_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u8 fc_tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u8 fc_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u8 fc_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u8 fc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u8 fc_gw_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* 2 bytes unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 fc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) __be32 fc_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __be32 fc_gw4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct in6_addr fc_gw6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int fc_oif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u32 fc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u32 fc_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __be32 fc_prefsrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 fc_nh_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct nlattr *fc_mx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct rtnexthop *fc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int fc_mx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int fc_mp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 fc_flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u32 fc_nlflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct nl_info fc_nlinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct nlattr *fc_encap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u16 fc_encap_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct fib_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct rtable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct fib_nh_exception {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct fib_nh_exception __rcu *fnhe_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int fnhe_genid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) __be32 fnhe_daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 fnhe_pmtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bool fnhe_mtu_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) __be32 fnhe_gw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long fnhe_expires;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct rtable __rcu *fnhe_rth_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct rtable __rcu *fnhe_rth_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long fnhe_stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct fnhe_hash_bucket {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct fib_nh_exception __rcu *chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define FNHE_HASH_SHIFT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define FNHE_HASH_SIZE (1 << FNHE_HASH_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define FNHE_RECLAIM_DEPTH 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct fib_nh_common {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct net_device *nhc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int nhc_oif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned char nhc_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u8 nhc_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u8 nhc_gw_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned char nhc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct lwtunnel_state *nhc_lwtstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __be32 ipv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct in6_addr ipv6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) } nhc_gw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int nhc_weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) atomic_t nhc_upper_bound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* v4 specific, but allows fib6_nh with v4 routes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct rtable __rcu * __percpu *nhc_pcpu_rth_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct rtable __rcu *nhc_rth_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct fnhe_hash_bucket __rcu *nhc_exceptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct fib_nh {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct fib_nh_common nh_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct hlist_node nh_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct fib_info *nh_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_IP_ROUTE_CLASSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) __u32 nh_tclassid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) __be32 nh_saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int nh_saddr_genid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define fib_nh_family nh_common.nhc_family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define fib_nh_dev nh_common.nhc_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define fib_nh_oif nh_common.nhc_oif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define fib_nh_flags nh_common.nhc_flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define fib_nh_lws nh_common.nhc_lwtstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define fib_nh_scope nh_common.nhc_scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define fib_nh_gw_family nh_common.nhc_gw_family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define fib_nh_gw4 nh_common.nhc_gw.ipv4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define fib_nh_gw6 nh_common.nhc_gw.ipv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define fib_nh_weight nh_common.nhc_weight
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define fib_nh_upper_bound nh_common.nhc_upper_bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * This structure contains data shared by many of routes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct nexthop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct fib_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct hlist_node fib_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct hlist_node fib_lhash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct list_head nh_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct net *fib_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int fib_treeref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) refcount_t fib_clntref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int fib_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned char fib_dead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned char fib_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned char fib_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned char fib_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) __be32 fib_prefsrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 fib_tb_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 fib_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct dst_metrics *fib_metrics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define fib_mtu fib_metrics->metrics[RTAX_MTU-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define fib_window fib_metrics->metrics[RTAX_WINDOW-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define fib_rtt fib_metrics->metrics[RTAX_RTT-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int fib_nhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) bool fib_nh_is_v6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) bool nh_updated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct nexthop *nh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct fib_nh fib_nh[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #ifdef CONFIG_IP_MULTIPLE_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct fib_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct fib_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct fib_result {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) __be32 prefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned char prefixlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned char nh_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned char type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned char scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 tclassid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct fib_nh_common *nhc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct fib_info *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct fib_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct hlist_head *fa_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct fib_result_nl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __be32 fl_addr; /* To be looked up*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u32 fl_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned char fl_tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) unsigned char fl_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsigned char tb_id_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned char tb_id; /* Results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned char prefixlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned char nh_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned char type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned char scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #ifdef CONFIG_IP_MULTIPLE_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define FIB_TABLE_HASHSZ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define FIB_TABLE_HASHSZ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned char scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __be32 fib_result_prefsrc(struct net *net, struct fib_result *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define FIB_RES_NHC(res) ((res).nhc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define FIB_RES_DEV(res) (FIB_RES_NHC(res)->nhc_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define FIB_RES_OIF(res) (FIB_RES_NHC(res)->nhc_oif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct fib_rt_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct fib_info *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u32 tb_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) __be32 dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int dst_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u8 tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u8 offload:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) trap:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unused:6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct fib_entry_notifier_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct fib_notifier_info info; /* must be first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u32 dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int dst_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct fib_info *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) u8 tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u32 tb_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct fib_nh_notifier_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct fib_notifier_info info; /* must be first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct fib_nh *fib_nh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int call_fib4_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) enum fib_event_type event_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct fib_notifier_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct fib_notifier_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int __net_init fib4_notifier_init(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void __net_exit fib4_notifier_exit(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) void fib_info_notify_update(struct net *net, struct nl_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int fib_notify(struct net *net, struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct fib_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct hlist_node tb_hlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u32 tb_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int tb_num_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned long *tb_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned long __data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct fib_dump_filter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u32 table_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* filter_set is an optimization that an entry is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) bool filter_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) bool dump_routes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) bool dump_exceptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned char protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned char rt_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct fib_result *res, int fib_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int fib_table_insert(struct net *, struct fib_table *, struct fib_config *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int fib_table_delete(struct net *, struct fib_table *, struct fib_config *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct netlink_callback *cb, struct fib_dump_filter *filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int fib_table_flush(struct net *net, struct fib_table *table, bool flush_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct fib_table *fib_trie_unmerge(struct fib_table *main_tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) void fib_table_flush_external(struct fib_table *table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) void fib_free_table(struct fib_table *tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #ifndef CONFIG_IP_MULTIPLE_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #define TABLE_LOCAL_INDEX (RT_TABLE_LOCAL & (FIB_TABLE_HASHSZ - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define TABLE_MAIN_INDEX (RT_TABLE_MAIN & (FIB_TABLE_HASHSZ - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static inline struct fib_table *fib_get_table(struct net *net, u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct hlist_node *tb_hlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct hlist_head *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ptr = id == RT_TABLE_LOCAL ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) tb_hlist = rcu_dereference_rtnl(hlist_first_rcu(ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return hlist_entry(tb_hlist, struct fib_table, tb_hlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static inline struct fib_table *fib_new_table(struct net *net, u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return fib_get_table(net, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static inline int fib_lookup(struct net *net, const struct flowi4 *flp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct fib_result *res, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct fib_table *tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) tb = fib_get_table(net, RT_TABLE_MAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = fib_table_lookup(tb, flp, res, flags | FIB_LOOKUP_NOREF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static inline bool fib4_has_custom_rules(const struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static inline bool fib4_rule_default(const struct fib_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static inline int fib4_rules_dump(struct net *net, struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static inline unsigned int fib4_rules_seq_read(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static inline bool fib4_rules_early_flow_dissect(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct flowi4 *fl4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct flow_keys *flkeys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #else /* CONFIG_IP_MULTIPLE_TABLES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int __net_init fib4_rules_init(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) void __net_exit fib4_rules_exit(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct fib_table *fib_new_table(struct net *net, u32 id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct fib_table *fib_get_table(struct net *net, u32 id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int __fib_lookup(struct net *net, struct flowi4 *flp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct fib_result *res, unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static inline int fib_lookup(struct net *net, struct flowi4 *flp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct fib_result *res, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct fib_table *tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) flags |= FIB_LOOKUP_NOREF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (net->ipv4.fib_has_custom_rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return __fib_lookup(net, flp, res, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) res->tclassid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) tb = rcu_dereference_rtnl(net->ipv4.fib_main);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) err = fib_table_lookup(tb, flp, res, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) tb = rcu_dereference_rtnl(net->ipv4.fib_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) err = fib_table_lookup(tb, flp, res, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static inline bool fib4_has_custom_rules(const struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return net->ipv4.fib_has_custom_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) bool fib4_rule_default(const struct fib_rule *rule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int fib4_rules_dump(struct net *net, struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) unsigned int fib4_rules_seq_read(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static inline bool fib4_rules_early_flow_dissect(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct flowi4 *fl4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct flow_keys *flkeys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!net->ipv4.fib_rules_require_fldissect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) skb_flow_dissect_flow_keys(skb, flkeys, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) fl4->fl4_sport = flkeys->ports.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) fl4->fl4_dport = flkeys->ports.dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) fl4->flowi4_proto = flkeys->basic.ip_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) #endif /* CONFIG_IP_MULTIPLE_TABLES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Exported by fib_frontend.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) extern const struct nla_policy rtm_ipv4_policy[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) void ip_fib_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int fib_gw_from_via(struct fib_config *cfg, struct nlattr *nla,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) __be32 fib_compute_spec_dst(struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) u8 tos, int oif, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct in_device *idev, u32 *itag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #ifdef CONFIG_IP_ROUTE_CLASSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static inline int fib_num_tclassid_users(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return atomic_read(&net->ipv4.fib_num_tclassid_users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static inline int fib_num_tclassid_users(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int fib_unmerge(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (nhc->nhc_dev == dev ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Exported by fib_semantics.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int ip_fib_check_default(__be32 gw, struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int fib_sync_down_addr(struct net_device *dev, __be32 local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int fib_sync_up(struct net_device *dev, unsigned char nh_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) void fib_nhc_update_mtu(struct fib_nh_common *nhc, u32 new, u32 orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) #ifdef CONFIG_IP_ROUTE_MULTIPATH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) const struct sk_buff *skb, struct flow_keys *flkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int fib_check_nh(struct net *net, struct fib_nh *nh, u32 table, u8 scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) void fib_select_multipath(struct fib_result *res, int hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) void fib_select_path(struct net *net, struct fib_result *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct flowi4 *fl4, const struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int fib_nh_init(struct net *net, struct fib_nh *fib_nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct fib_config *cfg, int nh_weight,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void fib_nh_release(struct net *net, struct fib_nh *fib_nh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int fib_nh_common_init(struct net *net, struct fib_nh_common *nhc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct nlattr *fc_encap, u16 fc_encap_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) void *cfg, gfp_t gfp_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct netlink_ext_ack *extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) void fib_nh_common_release(struct fib_nh_common *nhc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Exported by fib_trie.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) void fib_trie_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct fib_table *fib_trie_table(u32 id, struct fib_table *alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) bool fib_lookup_good_nhc(const struct fib_nh_common *nhc, int fib_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) const struct flowi4 *flp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #ifdef CONFIG_IP_ROUTE_CLASSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct fib_nh_common *nhc = res->nhc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #ifdef CONFIG_IP_MULTIPLE_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) u32 rtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (nhc->nhc_family == AF_INET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct fib_nh *nh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) nh = container_of(nhc, struct fib_nh, nh_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *itag = nh->nh_tclassid << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *itag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #ifdef CONFIG_IP_MULTIPLE_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) rtag = res->tclassid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (*itag == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) *itag = (rtag<<16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) *itag |= (rtag>>16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) void fib_flush(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) void free_fib_info(struct fib_info *fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static inline void fib_info_hold(struct fib_info *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) refcount_inc(&fi->fib_clntref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static inline void fib_info_put(struct fib_info *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (refcount_dec_and_test(&fi->fib_clntref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) free_fib_info(fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int __net_init fib_proc_init(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) void __net_exit fib_proc_exit(struct net *net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static inline int fib_proc_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static inline void fib_proc_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct fib_dump_filter *filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct netlink_callback *cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) u8 rt_family, unsigned char *flags, bool skip_oif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int nh_weight, u8 rt_family, u32 nh_tclassid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #endif /* _NET_FIB_H */