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