root/include/net/ip6_fib.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ip6_dst_idev
  2. fib6_clean_expires
  3. fib6_set_expires
  4. fib6_check_expired
  5. fib6_get_cookie_safe
  6. rt6_get_cookie
  7. ip6_rt_put
  8. fib6_info_hold
  9. fib6_info_hold_safe
  10. fib6_info_release
  11. rt6_get_prefsrc
  12. fib6_metric_locked
  13. fib6_rules_early_flow_dissect
  14. fib6_rules_init
  15. fib6_rules_cleanup
  16. fib6_rule_default
  17. fib6_rules_dump
  18. fib6_rules_seq_read
  19. fib6_rules_early_flow_dissect

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

/* [<][>][^][v][top][bottom][index][help] */