1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 */ 8 9 #ifndef _IP6_FIB_H 10 #define _IP6_FIB_H 11 12 #include <linux/ipv6_route.h> 13 #include <linux/rtnetlink.h> 14 #include <linux/spinlock.h> 15 #include <linux/notifier.h> 16 #include <net/dst.h> 17 #include <net/flow.h> 18 #include <net/ip_fib.h> 19 #include <net/netlink.h> 20 #include <net/inetpeer.h> 21 #include <net/fib_notifier.h> 22 #include <linux/indirect_call_wrapper.h> 23 24 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 25 #define FIB6_TABLE_HASHSZ 256 26 #else 27 #define FIB6_TABLE_HASHSZ 1 28 #endif 29 30 #define RT6_DEBUG 2 31 32 #if RT6_DEBUG >= 3 33 #define RT6_TRACE(x...) pr_debug(x) 34 #else 35 #define RT6_TRACE(x...) do { ; } while (0) 36 #endif 37 38 struct rt6_info; 39 struct fib6_info; 40 41 struct fib6_config { 42 u32 fc_table; 43 u32 fc_metric; 44 int fc_dst_len; 45 int fc_src_len; 46 int fc_ifindex; 47 u32 fc_flags; 48 u32 fc_protocol; 49 u16 fc_type; /* only 8 bits are used */ 50 u16 fc_delete_all_nh : 1, 51 fc_ignore_dev_down:1, 52 __unused : 14; 53 u32 fc_nh_id; 54 55 struct in6_addr fc_dst; 56 struct in6_addr fc_src; 57 struct in6_addr fc_prefsrc; 58 struct in6_addr fc_gateway; 59 60 unsigned long fc_expires; 61 struct nlattr *fc_mx; 62 int fc_mx_len; 63 int fc_mp_len; 64 struct nlattr *fc_mp; 65 66 struct nl_info fc_nlinfo; 67 struct nlattr *fc_encap; 68 u16 fc_encap_type; 69 bool fc_is_fdb; 70 }; 71 72 struct fib6_node { 73 struct fib6_node __rcu *parent; 74 struct fib6_node __rcu *left; 75 struct fib6_node __rcu *right; 76 #ifdef CONFIG_IPV6_SUBTREES 77 struct fib6_node __rcu *subtree; 78 #endif 79 struct fib6_info __rcu *leaf; 80 81 __u16 fn_bit; /* bit key */ 82 __u16 fn_flags; 83 int fn_sernum; 84 struct fib6_info __rcu *rr_ptr; 85 struct rcu_head rcu; 86 }; 87 88 struct fib6_gc_args { 89 int timeout; 90 int more; 91 }; 92 93 #ifndef CONFIG_IPV6_SUBTREES 94 #define FIB6_SUBTREE(fn) NULL 95 96 static inline bool fib6_routes_require_src(const struct net *net) 97 { 98 return false; 99 } 100 101 static inline void fib6_routes_require_src_inc(struct net *net) {} 102 static inline void fib6_routes_require_src_dec(struct net *net) {} 103 104 #else 105 106 static inline bool fib6_routes_require_src(const struct net *net) 107 { 108 return net->ipv6.fib6_routes_require_src > 0; 109 } 110 111 static inline void fib6_routes_require_src_inc(struct net *net) 112 { 113 net->ipv6.fib6_routes_require_src++; 114 } 115 116 static inline void fib6_routes_require_src_dec(struct net *net) 117 { 118 net->ipv6.fib6_routes_require_src--; 119 } 120 121 #define FIB6_SUBTREE(fn) (rcu_dereference_protected((fn)->subtree, 1)) 122 #endif 123 124 /* 125 * routing information 126 * 127 */ 128 129 struct rt6key { 130 struct in6_addr addr; 131 int plen; 132 }; 133 134 struct fib6_table; 135 136 struct rt6_exception_bucket { 137 struct hlist_head chain; 138 int depth; 139 }; 140 141 struct rt6_exception { 142 struct hlist_node hlist; 143 struct rt6_info *rt6i; 144 unsigned long stamp; 145 struct rcu_head rcu; 146 }; 147 148 #define FIB6_EXCEPTION_BUCKET_SIZE_SHIFT 10 149 #define FIB6_EXCEPTION_BUCKET_SIZE (1 << FIB6_EXCEPTION_BUCKET_SIZE_SHIFT) 150 #define FIB6_MAX_DEPTH 5 151 152 struct fib6_nh { 153 struct fib_nh_common nh_common; 154 155 #ifdef CONFIG_IPV6_ROUTER_PREF 156 unsigned long last_probe; 157 #endif 158 159 struct rt6_info * __percpu *rt6i_pcpu; 160 struct rt6_exception_bucket __rcu *rt6i_exception_bucket; 161 }; 162 163 struct fib6_info { 164 struct fib6_table *fib6_table; 165 struct fib6_info __rcu *fib6_next; 166 struct fib6_node __rcu *fib6_node; 167 168 /* Multipath routes: 169 * siblings is a list of fib6_info that have the the same metric/weight, 170 * destination, but not the same gateway. nsiblings is just a cache 171 * to speed up lookup. 172 */ 173 union { 174 struct list_head fib6_siblings; 175 struct list_head nh_list; 176 }; 177 unsigned int fib6_nsiblings; 178 179 refcount_t fib6_ref; 180 unsigned long expires; 181 struct dst_metrics *fib6_metrics; 182 #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] 183 184 struct rt6key fib6_dst; 185 u32 fib6_flags; 186 struct rt6key fib6_src; 187 struct rt6key fib6_prefsrc; 188 189 u32 fib6_metric; 190 u8 fib6_protocol; 191 u8 fib6_type; 192 u8 should_flush:1, 193 dst_nocount:1, 194 dst_nopolicy:1, 195 fib6_destroying:1, 196 offload:1, 197 trap:1, 198 unused:2; 199 200 struct rcu_head rcu; 201 struct nexthop *nh; 202 struct fib6_nh fib6_nh[]; 203 }; 204 205 struct rt6_info { 206 struct dst_entry dst; 207 struct fib6_info __rcu *from; 208 int sernum; 209 210 struct rt6key rt6i_dst; 211 struct rt6key rt6i_src; 212 struct in6_addr rt6i_gateway; 213 struct inet6_dev *rt6i_idev; 214 u32 rt6i_flags; 215 216 struct list_head rt6i_uncached; 217 struct uncached_list *rt6i_uncached_list; 218 219 /* more non-fragment space at head required */ 220 unsigned short rt6i_nfheader_len; 221 }; 222 223 struct fib6_result { 224 struct fib6_nh *nh; 225 struct fib6_info *f6i; 226 u32 fib6_flags; 227 u8 fib6_type; 228 struct rt6_info *rt6; 229 }; 230 231 #define for_each_fib6_node_rt_rcu(fn) \ 232 for (rt = rcu_dereference((fn)->leaf); rt; \ 233 rt = rcu_dereference(rt->fib6_next)) 234 235 #define for_each_fib6_walker_rt(w) \ 236 for (rt = (w)->leaf; rt; \ 237 rt = rcu_dereference_protected(rt->fib6_next, 1)) 238 239 static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) 240 { 241 return ((struct rt6_info *)dst)->rt6i_idev; 242 } 243 244 static inline bool fib6_requires_src(const struct fib6_info *rt) 245 { 246 return rt->fib6_src.plen > 0; 247 } 248 249 static inline void fib6_clean_expires(struct fib6_info *f6i) 250 { 251 f6i->fib6_flags &= ~RTF_EXPIRES; 252 f6i->expires = 0; 253 } 254 255 static inline void fib6_set_expires(struct fib6_info *f6i, 256 unsigned long expires) 257 { 258 f6i->expires = expires; 259 f6i->fib6_flags |= RTF_EXPIRES; 260 } 261 262 static inline bool fib6_check_expired(const struct fib6_info *f6i) 263 { 264 if (f6i->fib6_flags & RTF_EXPIRES) 265 return time_after(jiffies, f6i->expires); 266 return false; 267 } 268 269 /* Function to safely get fn->sernum for passed in rt 270 * and store result in passed in cookie. 271 * Return true if we can get cookie safely 272 * Return false if not 273 */ 274 static inline bool fib6_get_cookie_safe(const struct fib6_info *f6i, 275 u32 *cookie) 276 { 277 struct fib6_node *fn; 278 bool status = false; 279 280 fn = rcu_dereference(f6i->fib6_node); 281 282 if (fn) { 283 *cookie = fn->fn_sernum; 284 /* pairs with smp_wmb() in fib6_update_sernum_upto_root() */ 285 smp_rmb(); 286 status = true; 287 } 288 289 return status; 290 } 291 292 static inline u32 rt6_get_cookie(const struct rt6_info *rt) 293 { 294 struct fib6_info *from; 295 u32 cookie = 0; 296 297 if (rt->sernum) 298 return rt->sernum; 299 300 rcu_read_lock(); 301 302 from = rcu_dereference(rt->from); 303 if (from) 304 fib6_get_cookie_safe(from, &cookie); 305 306 rcu_read_unlock(); 307 308 return cookie; 309 } 310 311 static inline void ip6_rt_put(struct rt6_info *rt) 312 { 313 /* dst_release() accepts a NULL parameter. 314 * We rely on dst being first structure in struct rt6_info 315 */ 316 BUILD_BUG_ON(offsetof(struct rt6_info, dst) != 0); 317 dst_release(&rt->dst); 318 } 319 320 struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh); 321 void fib6_info_destroy_rcu(struct rcu_head *head); 322 323 static inline void fib6_info_hold(struct fib6_info *f6i) 324 { 325 refcount_inc(&f6i->fib6_ref); 326 } 327 328 static inline bool fib6_info_hold_safe(struct fib6_info *f6i) 329 { 330 return refcount_inc_not_zero(&f6i->fib6_ref); 331 } 332 333 static inline void fib6_info_release(struct fib6_info *f6i) 334 { 335 if (f6i && refcount_dec_and_test(&f6i->fib6_ref)) 336 call_rcu(&f6i->rcu, fib6_info_destroy_rcu); 337 } 338 339 static inline void fib6_info_hw_flags_set(struct fib6_info *f6i, bool offload, 340 bool trap) 341 { 342 f6i->offload = offload; 343 f6i->trap = trap; 344 } 345 346 enum fib6_walk_state { 347 #ifdef CONFIG_IPV6_SUBTREES 348 FWS_S, 349 #endif 350 FWS_L, 351 FWS_R, 352 FWS_C, 353 FWS_U 354 }; 355 356 struct fib6_walker { 357 struct list_head lh; 358 struct fib6_node *root, *node; 359 struct fib6_info *leaf; 360 enum fib6_walk_state state; 361 unsigned int skip; 362 unsigned int count; 363 unsigned int skip_in_node; 364 int (*func)(struct fib6_walker *); 365 void *args; 366 }; 367 368 struct rt6_statistics { 369 __u32 fib_nodes; /* all fib6 nodes */ 370 __u32 fib_route_nodes; /* intermediate nodes */ 371 __u32 fib_rt_entries; /* rt entries in fib table */ 372 __u32 fib_rt_cache; /* cached rt entries in exception table */ 373 __u32 fib_discarded_routes; /* total number of routes delete */ 374 375 /* The following stats are not protected by any lock */ 376 atomic_t fib_rt_alloc; /* total number of routes alloced */ 377 atomic_t fib_rt_uncache; /* rt entries in uncached list */ 378 }; 379 380 #define RTN_TL_ROOT 0x0001 381 #define RTN_ROOT 0x0002 /* tree root node */ 382 #define RTN_RTINFO 0x0004 /* node with valid routing info */ 383 384 /* 385 * priority levels (or metrics) 386 * 387 */ 388 389 390 struct fib6_table { 391 struct hlist_node tb6_hlist; 392 u32 tb6_id; 393 spinlock_t tb6_lock; 394 struct fib6_node tb6_root; 395 struct inet_peer_base tb6_peers; 396 unsigned int flags; 397 unsigned int fib_seq; 398 #define RT6_TABLE_HAS_DFLT_ROUTER BIT(0) 399 }; 400 401 #define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC 402 #define RT6_TABLE_MAIN RT_TABLE_MAIN 403 #define RT6_TABLE_DFLT RT6_TABLE_MAIN 404 #define RT6_TABLE_INFO RT6_TABLE_MAIN 405 #define RT6_TABLE_PREFIX RT6_TABLE_MAIN 406 407 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 408 #define FIB6_TABLE_MIN 1 409 #define FIB6_TABLE_MAX RT_TABLE_MAX 410 #define RT6_TABLE_LOCAL RT_TABLE_LOCAL 411 #else 412 #define FIB6_TABLE_MIN RT_TABLE_MAIN 413 #define FIB6_TABLE_MAX FIB6_TABLE_MIN 414 #define RT6_TABLE_LOCAL RT6_TABLE_MAIN 415 #endif 416 417 typedef struct rt6_info *(*pol_lookup_t)(struct net *, 418 struct fib6_table *, 419 struct flowi6 *, 420 const struct sk_buff *, int); 421 422 struct fib6_entry_notifier_info { 423 struct fib_notifier_info info; /* must be first */ 424 struct fib6_info *rt; 425 unsigned int nsiblings; 426 }; 427 428 /* 429 * exported functions 430 */ 431 432 struct fib6_table *fib6_get_table(struct net *net, u32 id); 433 struct fib6_table *fib6_new_table(struct net *net, u32 id); 434 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, 435 const struct sk_buff *skb, 436 int flags, pol_lookup_t lookup); 437 438 /* called with rcu lock held; can return error pointer 439 * caller needs to select path 440 */ 441 int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6, 442 struct fib6_result *res, int flags); 443 444 /* called with rcu lock held; caller needs to select path */ 445 int fib6_table_lookup(struct net *net, struct fib6_table *table, 446 int oif, struct flowi6 *fl6, struct fib6_result *res, 447 int strict); 448 449 void fib6_select_path(const struct net *net, struct fib6_result *res, 450 struct flowi6 *fl6, int oif, bool have_oif_match, 451 const struct sk_buff *skb, int strict); 452 struct fib6_node *fib6_node_lookup(struct fib6_node *root, 453 const struct in6_addr *daddr, 454 const struct in6_addr *saddr); 455 456 struct fib6_node *fib6_locate(struct fib6_node *root, 457 const struct in6_addr *daddr, int dst_len, 458 const struct in6_addr *saddr, int src_len, 459 bool exact_match); 460 461 void fib6_clean_all(struct net *net, int (*func)(struct fib6_info *, void *arg), 462 void *arg); 463 void fib6_clean_all_skip_notify(struct net *net, 464 int (*func)(struct fib6_info *, void *arg), 465 void *arg); 466 467 int fib6_add(struct fib6_node *root, struct fib6_info *rt, 468 struct nl_info *info, struct netlink_ext_ack *extack); 469 int fib6_del(struct fib6_info *rt, struct nl_info *info); 470 471 static inline 472 void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr) 473 { 474 const struct fib6_info *from; 475 476 rcu_read_lock(); 477 478 from = rcu_dereference(rt->from); 479 if (from) { 480 *addr = from->fib6_prefsrc.addr; 481 } else { 482 struct in6_addr in6_zero = {}; 483 484 *addr = in6_zero; 485 } 486 487 rcu_read_unlock(); 488 } 489 490 int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, 491 struct fib6_config *cfg, gfp_t gfp_flags, 492 struct netlink_ext_ack *extack); 493 void fib6_nh_release(struct fib6_nh *fib6_nh); 494 495 int call_fib6_entry_notifiers(struct net *net, 496 enum fib_event_type event_type, 497 struct fib6_info *rt, 498 struct netlink_ext_ack *extack); 499 int call_fib6_multipath_entry_notifiers(struct net *net, 500 enum fib_event_type event_type, 501 struct fib6_info *rt, 502 unsigned int nsiblings, 503 struct netlink_ext_ack *extack); 504 int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt); 505 void fib6_rt_update(struct net *net, struct fib6_info *rt, 506 struct nl_info *info); 507 void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info, 508 unsigned int flags); 509 510 void fib6_run_gc(unsigned long expires, struct net *net, bool force); 511 512 void fib6_gc_cleanup(void); 513 514 int fib6_init(void); 515 516 struct ipv6_route_iter { 517 struct seq_net_private p; 518 struct fib6_walker w; 519 loff_t skip; 520 struct fib6_table *tbl; 521 int sernum; 522 }; 523 524 extern const struct seq_operations ipv6_route_seq_ops; 525 526 int call_fib6_notifier(struct notifier_block *nb, 527 enum fib_event_type event_type, 528 struct fib_notifier_info *info); 529 int call_fib6_notifiers(struct net *net, enum fib_event_type event_type, 530 struct fib_notifier_info *info); 531 532 int __net_init fib6_notifier_init(struct net *net); 533 void __net_exit fib6_notifier_exit(struct net *net); 534 535 unsigned int fib6_tables_seq_read(struct net *net); 536 int fib6_tables_dump(struct net *net, struct notifier_block *nb, 537 struct netlink_ext_ack *extack); 538 539 void fib6_update_sernum(struct net *net, struct fib6_info *rt); 540 void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt); 541 void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i); 542 543 void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val); 544 static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric) 545 { 546 return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric)); 547 } 548 549 #if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL) 550 struct bpf_iter__ipv6_route { 551 __bpf_md_ptr(struct bpf_iter_meta *, meta); 552 __bpf_md_ptr(struct fib6_info *, rt); 553 }; 554 #endif 555 556 INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_output(struct net *net, 557 struct fib6_table *table, 558 struct flowi6 *fl6, 559 const struct sk_buff *skb, 560 int flags)); 561 INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_input(struct net *net, 562 struct fib6_table *table, 563 struct flowi6 *fl6, 564 const struct sk_buff *skb, 565 int flags)); 566 INDIRECT_CALLABLE_DECLARE(struct rt6_info *__ip6_route_redirect(struct net *net, 567 struct fib6_table *table, 568 struct flowi6 *fl6, 569 const struct sk_buff *skb, 570 int flags)); 571 INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_lookup(struct net *net, 572 struct fib6_table *table, 573 struct flowi6 *fl6, 574 const struct sk_buff *skb, 575 int flags)); 576 static inline struct rt6_info *pol_lookup_func(pol_lookup_t lookup, 577 struct net *net, 578 struct fib6_table *table, 579 struct flowi6 *fl6, 580 const struct sk_buff *skb, 581 int flags) 582 { 583 return INDIRECT_CALL_4(lookup, 584 ip6_pol_route_output, 585 ip6_pol_route_input, 586 ip6_pol_route_lookup, 587 __ip6_route_redirect, 588 net, table, fl6, skb, flags); 589 } 590 591 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 592 static inline bool fib6_has_custom_rules(const struct net *net) 593 { 594 return net->ipv6.fib6_has_custom_rules; 595 } 596 597 int fib6_rules_init(void); 598 void fib6_rules_cleanup(void); 599 bool fib6_rule_default(const struct fib_rule *rule); 600 int fib6_rules_dump(struct net *net, struct notifier_block *nb, 601 struct netlink_ext_ack *extack); 602 unsigned int fib6_rules_seq_read(struct net *net); 603 604 static inline bool fib6_rules_early_flow_dissect(struct net *net, 605 struct sk_buff *skb, 606 struct flowi6 *fl6, 607 struct flow_keys *flkeys) 608 { 609 unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP; 610 611 if (!net->ipv6.fib6_rules_require_fldissect) 612 return false; 613 614 skb_flow_dissect_flow_keys(skb, flkeys, flag); 615 fl6->fl6_sport = flkeys->ports.src; 616 fl6->fl6_dport = flkeys->ports.dst; 617 fl6->flowi6_proto = flkeys->basic.ip_proto; 618 619 return true; 620 } 621 #else 622 static inline bool fib6_has_custom_rules(const struct net *net) 623 { 624 return false; 625 } 626 static inline int fib6_rules_init(void) 627 { 628 return 0; 629 } 630 static inline void fib6_rules_cleanup(void) 631 { 632 return ; 633 } 634 static inline bool fib6_rule_default(const struct fib_rule *rule) 635 { 636 return true; 637 } 638 static inline int fib6_rules_dump(struct net *net, struct notifier_block *nb, 639 struct netlink_ext_ack *extack) 640 { 641 return 0; 642 } 643 static inline unsigned int fib6_rules_seq_read(struct net *net) 644 { 645 return 0; 646 } 647 static inline bool fib6_rules_early_flow_dissect(struct net *net, 648 struct sk_buff *skb, 649 struct flowi6 *fl6, 650 struct flow_keys *flkeys) 651 { 652 return false; 653 } 654 #endif 655 #endif 656