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