xref: /linux-6.15/include/net/ip_fib.h (revision 1da177e4)
1*1da177e4SLinus Torvalds /*
2*1da177e4SLinus Torvalds  * INET		An implementation of the TCP/IP protocol suite for the LINUX
3*1da177e4SLinus Torvalds  *		operating system.  INET  is implemented using the  BSD Socket
4*1da177e4SLinus Torvalds  *		interface as the means of communication with the user level.
5*1da177e4SLinus Torvalds  *
6*1da177e4SLinus Torvalds  *		Definitions for the Forwarding Information Base.
7*1da177e4SLinus Torvalds  *
8*1da177e4SLinus Torvalds  * Authors:	A.N.Kuznetsov, <[email protected]>
9*1da177e4SLinus Torvalds  *
10*1da177e4SLinus Torvalds  *		This program is free software; you can redistribute it and/or
11*1da177e4SLinus Torvalds  *		modify it under the terms of the GNU General Public License
12*1da177e4SLinus Torvalds  *		as published by the Free Software Foundation; either version
13*1da177e4SLinus Torvalds  *		2 of the License, or (at your option) any later version.
14*1da177e4SLinus Torvalds  */
15*1da177e4SLinus Torvalds 
16*1da177e4SLinus Torvalds #ifndef _NET_IP_FIB_H
17*1da177e4SLinus Torvalds #define _NET_IP_FIB_H
18*1da177e4SLinus Torvalds 
19*1da177e4SLinus Torvalds #include <linux/config.h>
20*1da177e4SLinus Torvalds #include <net/flow.h>
21*1da177e4SLinus Torvalds #include <linux/seq_file.h>
22*1da177e4SLinus Torvalds 
23*1da177e4SLinus Torvalds /* WARNING: The ordering of these elements must match ordering
24*1da177e4SLinus Torvalds  *          of RTA_* rtnetlink attribute numbers.
25*1da177e4SLinus Torvalds  */
26*1da177e4SLinus Torvalds struct kern_rta {
27*1da177e4SLinus Torvalds 	void		*rta_dst;
28*1da177e4SLinus Torvalds 	void		*rta_src;
29*1da177e4SLinus Torvalds 	int		*rta_iif;
30*1da177e4SLinus Torvalds 	int		*rta_oif;
31*1da177e4SLinus Torvalds 	void		*rta_gw;
32*1da177e4SLinus Torvalds 	u32		*rta_priority;
33*1da177e4SLinus Torvalds 	void		*rta_prefsrc;
34*1da177e4SLinus Torvalds 	struct rtattr	*rta_mx;
35*1da177e4SLinus Torvalds 	struct rtattr	*rta_mp;
36*1da177e4SLinus Torvalds 	unsigned char	*rta_protoinfo;
37*1da177e4SLinus Torvalds 	u32		*rta_flow;
38*1da177e4SLinus Torvalds 	struct rta_cacheinfo *rta_ci;
39*1da177e4SLinus Torvalds 	struct rta_session *rta_sess;
40*1da177e4SLinus Torvalds 	u32		*rta_mp_alg;
41*1da177e4SLinus Torvalds };
42*1da177e4SLinus Torvalds 
43*1da177e4SLinus Torvalds struct fib_info;
44*1da177e4SLinus Torvalds 
45*1da177e4SLinus Torvalds struct fib_nh {
46*1da177e4SLinus Torvalds 	struct net_device	*nh_dev;
47*1da177e4SLinus Torvalds 	struct hlist_node	nh_hash;
48*1da177e4SLinus Torvalds 	struct fib_info		*nh_parent;
49*1da177e4SLinus Torvalds 	unsigned		nh_flags;
50*1da177e4SLinus Torvalds 	unsigned char		nh_scope;
51*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH
52*1da177e4SLinus Torvalds 	int			nh_weight;
53*1da177e4SLinus Torvalds 	int			nh_power;
54*1da177e4SLinus Torvalds #endif
55*1da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ROUTE
56*1da177e4SLinus Torvalds 	__u32			nh_tclassid;
57*1da177e4SLinus Torvalds #endif
58*1da177e4SLinus Torvalds 	int			nh_oif;
59*1da177e4SLinus Torvalds 	u32			nh_gw;
60*1da177e4SLinus Torvalds };
61*1da177e4SLinus Torvalds 
62*1da177e4SLinus Torvalds /*
63*1da177e4SLinus Torvalds  * This structure contains data shared by many of routes.
64*1da177e4SLinus Torvalds  */
65*1da177e4SLinus Torvalds 
66*1da177e4SLinus Torvalds struct fib_info {
67*1da177e4SLinus Torvalds 	struct hlist_node	fib_hash;
68*1da177e4SLinus Torvalds 	struct hlist_node	fib_lhash;
69*1da177e4SLinus Torvalds 	int			fib_treeref;
70*1da177e4SLinus Torvalds 	atomic_t		fib_clntref;
71*1da177e4SLinus Torvalds 	int			fib_dead;
72*1da177e4SLinus Torvalds 	unsigned		fib_flags;
73*1da177e4SLinus Torvalds 	int			fib_protocol;
74*1da177e4SLinus Torvalds 	u32			fib_prefsrc;
75*1da177e4SLinus Torvalds 	u32			fib_priority;
76*1da177e4SLinus Torvalds 	u32			fib_metrics[RTAX_MAX];
77*1da177e4SLinus Torvalds #define fib_mtu fib_metrics[RTAX_MTU-1]
78*1da177e4SLinus Torvalds #define fib_window fib_metrics[RTAX_WINDOW-1]
79*1da177e4SLinus Torvalds #define fib_rtt fib_metrics[RTAX_RTT-1]
80*1da177e4SLinus Torvalds #define fib_advmss fib_metrics[RTAX_ADVMSS-1]
81*1da177e4SLinus Torvalds 	int			fib_nhs;
82*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH
83*1da177e4SLinus Torvalds 	int			fib_power;
84*1da177e4SLinus Torvalds #endif
85*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
86*1da177e4SLinus Torvalds 	u32			fib_mp_alg;
87*1da177e4SLinus Torvalds #endif
88*1da177e4SLinus Torvalds 	struct fib_nh		fib_nh[0];
89*1da177e4SLinus Torvalds #define fib_dev		fib_nh[0].nh_dev
90*1da177e4SLinus Torvalds };
91*1da177e4SLinus Torvalds 
92*1da177e4SLinus Torvalds 
93*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES
94*1da177e4SLinus Torvalds struct fib_rule;
95*1da177e4SLinus Torvalds #endif
96*1da177e4SLinus Torvalds 
97*1da177e4SLinus Torvalds struct fib_result {
98*1da177e4SLinus Torvalds 	unsigned char	prefixlen;
99*1da177e4SLinus Torvalds 	unsigned char	nh_sel;
100*1da177e4SLinus Torvalds 	unsigned char	type;
101*1da177e4SLinus Torvalds 	unsigned char	scope;
102*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
103*1da177e4SLinus Torvalds 	__u32           network;
104*1da177e4SLinus Torvalds 	__u32           netmask;
105*1da177e4SLinus Torvalds #endif
106*1da177e4SLinus Torvalds 	struct fib_info *fi;
107*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES
108*1da177e4SLinus Torvalds 	struct fib_rule	*r;
109*1da177e4SLinus Torvalds #endif
110*1da177e4SLinus Torvalds };
111*1da177e4SLinus Torvalds 
112*1da177e4SLinus Torvalds 
113*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH
114*1da177e4SLinus Torvalds 
115*1da177e4SLinus Torvalds #define FIB_RES_NH(res)		((res).fi->fib_nh[(res).nh_sel])
116*1da177e4SLinus Torvalds #define FIB_RES_RESET(res)	((res).nh_sel = 0)
117*1da177e4SLinus Torvalds 
118*1da177e4SLinus Torvalds #else /* CONFIG_IP_ROUTE_MULTIPATH */
119*1da177e4SLinus Torvalds 
120*1da177e4SLinus Torvalds #define FIB_RES_NH(res)		((res).fi->fib_nh[0])
121*1da177e4SLinus Torvalds #define FIB_RES_RESET(res)
122*1da177e4SLinus Torvalds 
123*1da177e4SLinus Torvalds #endif /* CONFIG_IP_ROUTE_MULTIPATH */
124*1da177e4SLinus Torvalds 
125*1da177e4SLinus Torvalds #define FIB_RES_PREFSRC(res)		((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
126*1da177e4SLinus Torvalds #define FIB_RES_GW(res)			(FIB_RES_NH(res).nh_gw)
127*1da177e4SLinus Torvalds #define FIB_RES_DEV(res)		(FIB_RES_NH(res).nh_dev)
128*1da177e4SLinus Torvalds #define FIB_RES_OIF(res)		(FIB_RES_NH(res).nh_oif)
129*1da177e4SLinus Torvalds 
130*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
131*1da177e4SLinus Torvalds #define FIB_RES_NETWORK(res)		((res).network)
132*1da177e4SLinus Torvalds #define FIB_RES_NETMASK(res)	        ((res).netmask)
133*1da177e4SLinus Torvalds #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
134*1da177e4SLinus Torvalds #define FIB_RES_NETWORK(res)		(0)
135*1da177e4SLinus Torvalds #define FIB_RES_NETMASK(res)	        (0)
136*1da177e4SLinus Torvalds #endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
137*1da177e4SLinus Torvalds 
138*1da177e4SLinus Torvalds struct fib_table {
139*1da177e4SLinus Torvalds 	unsigned char	tb_id;
140*1da177e4SLinus Torvalds 	unsigned	tb_stamp;
141*1da177e4SLinus Torvalds 	int		(*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
142*1da177e4SLinus Torvalds 	int		(*tb_insert)(struct fib_table *table, struct rtmsg *r,
143*1da177e4SLinus Torvalds 				     struct kern_rta *rta, struct nlmsghdr *n,
144*1da177e4SLinus Torvalds 				     struct netlink_skb_parms *req);
145*1da177e4SLinus Torvalds 	int		(*tb_delete)(struct fib_table *table, struct rtmsg *r,
146*1da177e4SLinus Torvalds 				     struct kern_rta *rta, struct nlmsghdr *n,
147*1da177e4SLinus Torvalds 				     struct netlink_skb_parms *req);
148*1da177e4SLinus Torvalds 	int		(*tb_dump)(struct fib_table *table, struct sk_buff *skb,
149*1da177e4SLinus Torvalds 				     struct netlink_callback *cb);
150*1da177e4SLinus Torvalds 	int		(*tb_flush)(struct fib_table *table);
151*1da177e4SLinus Torvalds 	void		(*tb_select_default)(struct fib_table *table,
152*1da177e4SLinus Torvalds 					     const struct flowi *flp, struct fib_result *res);
153*1da177e4SLinus Torvalds 
154*1da177e4SLinus Torvalds 	unsigned char	tb_data[0];
155*1da177e4SLinus Torvalds };
156*1da177e4SLinus Torvalds 
157*1da177e4SLinus Torvalds #ifndef CONFIG_IP_MULTIPLE_TABLES
158*1da177e4SLinus Torvalds 
159*1da177e4SLinus Torvalds extern struct fib_table *ip_fib_local_table;
160*1da177e4SLinus Torvalds extern struct fib_table *ip_fib_main_table;
161*1da177e4SLinus Torvalds 
162*1da177e4SLinus Torvalds static inline struct fib_table *fib_get_table(int id)
163*1da177e4SLinus Torvalds {
164*1da177e4SLinus Torvalds 	if (id != RT_TABLE_LOCAL)
165*1da177e4SLinus Torvalds 		return ip_fib_main_table;
166*1da177e4SLinus Torvalds 	return ip_fib_local_table;
167*1da177e4SLinus Torvalds }
168*1da177e4SLinus Torvalds 
169*1da177e4SLinus Torvalds static inline struct fib_table *fib_new_table(int id)
170*1da177e4SLinus Torvalds {
171*1da177e4SLinus Torvalds 	return fib_get_table(id);
172*1da177e4SLinus Torvalds }
173*1da177e4SLinus Torvalds 
174*1da177e4SLinus Torvalds static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
175*1da177e4SLinus Torvalds {
176*1da177e4SLinus Torvalds 	if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
177*1da177e4SLinus Torvalds 	    ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
178*1da177e4SLinus Torvalds 		return -ENETUNREACH;
179*1da177e4SLinus Torvalds 	return 0;
180*1da177e4SLinus Torvalds }
181*1da177e4SLinus Torvalds 
182*1da177e4SLinus Torvalds static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
183*1da177e4SLinus Torvalds {
184*1da177e4SLinus Torvalds 	if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
185*1da177e4SLinus Torvalds 		ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
186*1da177e4SLinus Torvalds }
187*1da177e4SLinus Torvalds 
188*1da177e4SLinus Torvalds #else /* CONFIG_IP_MULTIPLE_TABLES */
189*1da177e4SLinus Torvalds #define ip_fib_local_table (fib_tables[RT_TABLE_LOCAL])
190*1da177e4SLinus Torvalds #define ip_fib_main_table (fib_tables[RT_TABLE_MAIN])
191*1da177e4SLinus Torvalds 
192*1da177e4SLinus Torvalds extern struct fib_table * fib_tables[RT_TABLE_MAX+1];
193*1da177e4SLinus Torvalds extern int fib_lookup(const struct flowi *flp, struct fib_result *res);
194*1da177e4SLinus Torvalds extern struct fib_table *__fib_new_table(int id);
195*1da177e4SLinus Torvalds extern void fib_rule_put(struct fib_rule *r);
196*1da177e4SLinus Torvalds 
197*1da177e4SLinus Torvalds static inline struct fib_table *fib_get_table(int id)
198*1da177e4SLinus Torvalds {
199*1da177e4SLinus Torvalds 	if (id == 0)
200*1da177e4SLinus Torvalds 		id = RT_TABLE_MAIN;
201*1da177e4SLinus Torvalds 
202*1da177e4SLinus Torvalds 	return fib_tables[id];
203*1da177e4SLinus Torvalds }
204*1da177e4SLinus Torvalds 
205*1da177e4SLinus Torvalds static inline struct fib_table *fib_new_table(int id)
206*1da177e4SLinus Torvalds {
207*1da177e4SLinus Torvalds 	if (id == 0)
208*1da177e4SLinus Torvalds 		id = RT_TABLE_MAIN;
209*1da177e4SLinus Torvalds 
210*1da177e4SLinus Torvalds 	return fib_tables[id] ? : __fib_new_table(id);
211*1da177e4SLinus Torvalds }
212*1da177e4SLinus Torvalds 
213*1da177e4SLinus Torvalds extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
214*1da177e4SLinus Torvalds 
215*1da177e4SLinus Torvalds #endif /* CONFIG_IP_MULTIPLE_TABLES */
216*1da177e4SLinus Torvalds 
217*1da177e4SLinus Torvalds /* Exported by fib_frontend.c */
218*1da177e4SLinus Torvalds extern void		ip_fib_init(void);
219*1da177e4SLinus Torvalds extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
220*1da177e4SLinus Torvalds extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
221*1da177e4SLinus Torvalds extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
222*1da177e4SLinus Torvalds extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
223*1da177e4SLinus Torvalds extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
224*1da177e4SLinus Torvalds 			       struct net_device *dev, u32 *spec_dst, u32 *itag);
225*1da177e4SLinus Torvalds extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
226*1da177e4SLinus Torvalds 
227*1da177e4SLinus Torvalds /* Exported by fib_semantics.c */
228*1da177e4SLinus Torvalds extern int ip_fib_check_default(u32 gw, struct net_device *dev);
229*1da177e4SLinus Torvalds extern int fib_sync_down(u32 local, struct net_device *dev, int force);
230*1da177e4SLinus Torvalds extern int fib_sync_up(struct net_device *dev);
231*1da177e4SLinus Torvalds extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
232*1da177e4SLinus Torvalds 			       struct kern_rta *rta, struct rtentry *r);
233*1da177e4SLinus Torvalds extern u32  __fib_res_prefsrc(struct fib_result *res);
234*1da177e4SLinus Torvalds 
235*1da177e4SLinus Torvalds /* Exported by fib_hash.c */
236*1da177e4SLinus Torvalds extern struct fib_table *fib_hash_init(int id);
237*1da177e4SLinus Torvalds 
238*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES
239*1da177e4SLinus Torvalds /* Exported by fib_rules.c */
240*1da177e4SLinus Torvalds 
241*1da177e4SLinus Torvalds extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
242*1da177e4SLinus Torvalds extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
243*1da177e4SLinus Torvalds extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb);
244*1da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ROUTE
245*1da177e4SLinus Torvalds extern u32 fib_rules_tclass(struct fib_result *res);
246*1da177e4SLinus Torvalds #endif
247*1da177e4SLinus Torvalds extern void fib_rules_init(void);
248*1da177e4SLinus Torvalds #endif
249*1da177e4SLinus Torvalds 
250*1da177e4SLinus Torvalds static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
251*1da177e4SLinus Torvalds {
252*1da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ROUTE
253*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES
254*1da177e4SLinus Torvalds 	u32 rtag;
255*1da177e4SLinus Torvalds #endif
256*1da177e4SLinus Torvalds 	*itag = FIB_RES_NH(*res).nh_tclassid<<16;
257*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES
258*1da177e4SLinus Torvalds 	rtag = fib_rules_tclass(res);
259*1da177e4SLinus Torvalds 	if (*itag == 0)
260*1da177e4SLinus Torvalds 		*itag = (rtag<<16);
261*1da177e4SLinus Torvalds 	*itag |= (rtag>>16);
262*1da177e4SLinus Torvalds #endif
263*1da177e4SLinus Torvalds #endif
264*1da177e4SLinus Torvalds }
265*1da177e4SLinus Torvalds 
266*1da177e4SLinus Torvalds extern void free_fib_info(struct fib_info *fi);
267*1da177e4SLinus Torvalds 
268*1da177e4SLinus Torvalds static inline void fib_info_put(struct fib_info *fi)
269*1da177e4SLinus Torvalds {
270*1da177e4SLinus Torvalds 	if (atomic_dec_and_test(&fi->fib_clntref))
271*1da177e4SLinus Torvalds 		free_fib_info(fi);
272*1da177e4SLinus Torvalds }
273*1da177e4SLinus Torvalds 
274*1da177e4SLinus Torvalds static inline void fib_res_put(struct fib_result *res)
275*1da177e4SLinus Torvalds {
276*1da177e4SLinus Torvalds 	if (res->fi)
277*1da177e4SLinus Torvalds 		fib_info_put(res->fi);
278*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES
279*1da177e4SLinus Torvalds 	if (res->r)
280*1da177e4SLinus Torvalds 		fib_rule_put(res->r);
281*1da177e4SLinus Torvalds #endif
282*1da177e4SLinus Torvalds }
283*1da177e4SLinus Torvalds 
284*1da177e4SLinus Torvalds #endif  /* _NET_FIB_H */
285