root/include/net/ip_fib.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. fib_get_table
  2. fib_new_table
  3. fib_lookup
  4. fib4_rule_default
  5. fib4_rules_dump
  6. fib4_rules_seq_read
  7. fib4_rules_early_flow_dissect
  8. fib_lookup
  9. fib4_rules_early_flow_dissect
  10. fib_num_tclassid_users
  11. fib_num_tclassid_users
  12. nhc_l3mdev_matches_dev
  13. fib_combine_itag
  14. fib_info_hold
  15. fib_info_put
  16. fib_proc_init
  17. fib_proc_exit

   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[0];
 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_entry_notifier_info {
 208         struct fib_notifier_info info; /* must be first */
 209         u32 dst;
 210         int dst_len;
 211         struct fib_info *fi;
 212         u8 tos;
 213         u8 type;
 214         u32 tb_id;
 215 };
 216 
 217 struct fib_nh_notifier_info {
 218         struct fib_notifier_info info; /* must be first */
 219         struct fib_nh *fib_nh;
 220 };
 221 
 222 int call_fib4_notifier(struct notifier_block *nb, struct net *net,
 223                        enum fib_event_type event_type,
 224                        struct fib_notifier_info *info);
 225 int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
 226                         struct fib_notifier_info *info);
 227 
 228 int __net_init fib4_notifier_init(struct net *net);
 229 void __net_exit fib4_notifier_exit(struct net *net);
 230 
 231 void fib_info_notify_update(struct net *net, struct nl_info *info);
 232 void fib_notify(struct net *net, struct notifier_block *nb);
 233 
 234 struct fib_table {
 235         struct hlist_node       tb_hlist;
 236         u32                     tb_id;
 237         int                     tb_num_default;
 238         struct rcu_head         rcu;
 239         unsigned long           *tb_data;
 240         unsigned long           __data[0];
 241 };
 242 
 243 struct fib_dump_filter {
 244         u32                     table_id;
 245         /* filter_set is an optimization that an entry is set */
 246         bool                    filter_set;
 247         bool                    dump_routes;
 248         bool                    dump_exceptions;
 249         unsigned char           protocol;
 250         unsigned char           rt_type;
 251         unsigned int            flags;
 252         struct net_device       *dev;
 253 };
 254 
 255 int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
 256                      struct fib_result *res, int fib_flags);
 257 int fib_table_insert(struct net *, struct fib_table *, struct fib_config *,
 258                      struct netlink_ext_ack *extack);
 259 int fib_table_delete(struct net *, struct fib_table *, struct fib_config *,
 260                      struct netlink_ext_ack *extack);
 261 int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
 262                    struct netlink_callback *cb, struct fib_dump_filter *filter);
 263 int fib_table_flush(struct net *net, struct fib_table *table, bool flush_all);
 264 struct fib_table *fib_trie_unmerge(struct fib_table *main_tb);
 265 void fib_table_flush_external(struct fib_table *table);
 266 void fib_free_table(struct fib_table *tb);
 267 
 268 #ifndef CONFIG_IP_MULTIPLE_TABLES
 269 
 270 #define TABLE_LOCAL_INDEX       (RT_TABLE_LOCAL & (FIB_TABLE_HASHSZ - 1))
 271 #define TABLE_MAIN_INDEX        (RT_TABLE_MAIN  & (FIB_TABLE_HASHSZ - 1))
 272 
 273 static inline struct fib_table *fib_get_table(struct net *net, u32 id)
 274 {
 275         struct hlist_node *tb_hlist;
 276         struct hlist_head *ptr;
 277 
 278         ptr = id == RT_TABLE_LOCAL ?
 279                 &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] :
 280                 &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
 281 
 282         tb_hlist = rcu_dereference_rtnl(hlist_first_rcu(ptr));
 283 
 284         return hlist_entry(tb_hlist, struct fib_table, tb_hlist);
 285 }
 286 
 287 static inline struct fib_table *fib_new_table(struct net *net, u32 id)
 288 {
 289         return fib_get_table(net, id);
 290 }
 291 
 292 static inline int fib_lookup(struct net *net, const struct flowi4 *flp,
 293                              struct fib_result *res, unsigned int flags)
 294 {
 295         struct fib_table *tb;
 296         int err = -ENETUNREACH;
 297 
 298         rcu_read_lock();
 299 
 300         tb = fib_get_table(net, RT_TABLE_MAIN);
 301         if (tb)
 302                 err = fib_table_lookup(tb, flp, res, flags | FIB_LOOKUP_NOREF);
 303 
 304         if (err == -EAGAIN)
 305                 err = -ENETUNREACH;
 306 
 307         rcu_read_unlock();
 308 
 309         return err;
 310 }
 311 
 312 static inline bool fib4_rule_default(const struct fib_rule *rule)
 313 {
 314         return true;
 315 }
 316 
 317 static inline int fib4_rules_dump(struct net *net, struct notifier_block *nb)
 318 {
 319         return 0;
 320 }
 321 
 322 static inline unsigned int fib4_rules_seq_read(struct net *net)
 323 {
 324         return 0;
 325 }
 326 
 327 static inline bool fib4_rules_early_flow_dissect(struct net *net,
 328                                                  struct sk_buff *skb,
 329                                                  struct flowi4 *fl4,
 330                                                  struct flow_keys *flkeys)
 331 {
 332         return false;
 333 }
 334 #else /* CONFIG_IP_MULTIPLE_TABLES */
 335 int __net_init fib4_rules_init(struct net *net);
 336 void __net_exit fib4_rules_exit(struct net *net);
 337 
 338 struct fib_table *fib_new_table(struct net *net, u32 id);
 339 struct fib_table *fib_get_table(struct net *net, u32 id);
 340 
 341 int __fib_lookup(struct net *net, struct flowi4 *flp,
 342                  struct fib_result *res, unsigned int flags);
 343 
 344 static inline int fib_lookup(struct net *net, struct flowi4 *flp,
 345                              struct fib_result *res, unsigned int flags)
 346 {
 347         struct fib_table *tb;
 348         int err = -ENETUNREACH;
 349 
 350         flags |= FIB_LOOKUP_NOREF;
 351         if (net->ipv4.fib_has_custom_rules)
 352                 return __fib_lookup(net, flp, res, flags);
 353 
 354         rcu_read_lock();
 355 
 356         res->tclassid = 0;
 357 
 358         tb = rcu_dereference_rtnl(net->ipv4.fib_main);
 359         if (tb)
 360                 err = fib_table_lookup(tb, flp, res, flags);
 361 
 362         if (!err)
 363                 goto out;
 364 
 365         tb = rcu_dereference_rtnl(net->ipv4.fib_default);
 366         if (tb)
 367                 err = fib_table_lookup(tb, flp, res, flags);
 368 
 369 out:
 370         if (err == -EAGAIN)
 371                 err = -ENETUNREACH;
 372 
 373         rcu_read_unlock();
 374 
 375         return err;
 376 }
 377 
 378 bool fib4_rule_default(const struct fib_rule *rule);
 379 int fib4_rules_dump(struct net *net, struct notifier_block *nb);
 380 unsigned int fib4_rules_seq_read(struct net *net);
 381 
 382 static inline bool fib4_rules_early_flow_dissect(struct net *net,
 383                                                  struct sk_buff *skb,
 384                                                  struct flowi4 *fl4,
 385                                                  struct flow_keys *flkeys)
 386 {
 387         unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
 388 
 389         if (!net->ipv4.fib_rules_require_fldissect)
 390                 return false;
 391 
 392         skb_flow_dissect_flow_keys(skb, flkeys, flag);
 393         fl4->fl4_sport = flkeys->ports.src;
 394         fl4->fl4_dport = flkeys->ports.dst;
 395         fl4->flowi4_proto = flkeys->basic.ip_proto;
 396 
 397         return true;
 398 }
 399 
 400 #endif /* CONFIG_IP_MULTIPLE_TABLES */
 401 
 402 /* Exported by fib_frontend.c */
 403 extern const struct nla_policy rtm_ipv4_policy[];
 404 void ip_fib_init(void);
 405 int fib_gw_from_via(struct fib_config *cfg, struct nlattr *nla,
 406                     struct netlink_ext_ack *extack);
 407 __be32 fib_compute_spec_dst(struct sk_buff *skb);
 408 bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev);
 409 int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
 410                         u8 tos, int oif, struct net_device *dev,
 411                         struct in_device *idev, u32 *itag);
 412 #ifdef CONFIG_IP_ROUTE_CLASSID
 413 static inline int fib_num_tclassid_users(struct net *net)
 414 {
 415         return net->ipv4.fib_num_tclassid_users;
 416 }
 417 #else
 418 static inline int fib_num_tclassid_users(struct net *net)
 419 {
 420         return 0;
 421 }
 422 #endif
 423 int fib_unmerge(struct net *net);
 424 
 425 static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
 426 const struct net_device *dev)
 427 {
 428         if (nhc->nhc_dev == dev ||
 429             l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
 430                 return true;
 431 
 432         return false;
 433 }
 434 
 435 /* Exported by fib_semantics.c */
 436 int ip_fib_check_default(__be32 gw, struct net_device *dev);
 437 int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
 438 int fib_sync_down_addr(struct net_device *dev, __be32 local);
 439 int fib_sync_up(struct net_device *dev, unsigned char nh_flags);
 440 void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
 441 void fib_nhc_update_mtu(struct fib_nh_common *nhc, u32 new, u32 orig);
 442 
 443 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 444 int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 445                        const struct sk_buff *skb, struct flow_keys *flkeys);
 446 #endif
 447 int fib_check_nh(struct net *net, struct fib_nh *nh, u32 table, u8 scope,
 448                  struct netlink_ext_ack *extack);
 449 void fib_select_multipath(struct fib_result *res, int hash);
 450 void fib_select_path(struct net *net, struct fib_result *res,
 451                      struct flowi4 *fl4, const struct sk_buff *skb);
 452 
 453 int fib_nh_init(struct net *net, struct fib_nh *fib_nh,
 454                 struct fib_config *cfg, int nh_weight,
 455                 struct netlink_ext_ack *extack);
 456 void fib_nh_release(struct net *net, struct fib_nh *fib_nh);
 457 int fib_nh_common_init(struct fib_nh_common *nhc, struct nlattr *fc_encap,
 458                        u16 fc_encap_type, void *cfg, gfp_t gfp_flags,
 459                        struct netlink_ext_ack *extack);
 460 void fib_nh_common_release(struct fib_nh_common *nhc);
 461 
 462 /* Exported by fib_trie.c */
 463 void fib_trie_init(void);
 464 struct fib_table *fib_trie_table(u32 id, struct fib_table *alias);
 465 
 466 static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
 467 {
 468 #ifdef CONFIG_IP_ROUTE_CLASSID
 469         struct fib_nh_common *nhc = res->nhc;
 470 #ifdef CONFIG_IP_MULTIPLE_TABLES
 471         u32 rtag;
 472 #endif
 473         if (nhc->nhc_family == AF_INET) {
 474                 struct fib_nh *nh;
 475 
 476                 nh = container_of(nhc, struct fib_nh, nh_common);
 477                 *itag = nh->nh_tclassid << 16;
 478         } else {
 479                 *itag = 0;
 480         }
 481 
 482 #ifdef CONFIG_IP_MULTIPLE_TABLES
 483         rtag = res->tclassid;
 484         if (*itag == 0)
 485                 *itag = (rtag<<16);
 486         *itag |= (rtag>>16);
 487 #endif
 488 #endif
 489 }
 490 
 491 void fib_flush(struct net *net);
 492 void free_fib_info(struct fib_info *fi);
 493 
 494 static inline void fib_info_hold(struct fib_info *fi)
 495 {
 496         refcount_inc(&fi->fib_clntref);
 497 }
 498 
 499 static inline void fib_info_put(struct fib_info *fi)
 500 {
 501         if (refcount_dec_and_test(&fi->fib_clntref))
 502                 free_fib_info(fi);
 503 }
 504 
 505 #ifdef CONFIG_PROC_FS
 506 int __net_init fib_proc_init(struct net *net);
 507 void __net_exit fib_proc_exit(struct net *net);
 508 #else
 509 static inline int fib_proc_init(struct net *net)
 510 {
 511         return 0;
 512 }
 513 static inline void fib_proc_exit(struct net *net)
 514 {
 515 }
 516 #endif
 517 
 518 u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr);
 519 
 520 int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
 521                           struct fib_dump_filter *filter,
 522                           struct netlink_callback *cb);
 523 
 524 int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh,
 525                      u8 rt_family, unsigned char *flags, bool skip_oif);
 526 int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh,
 527                     int nh_weight, u8 rt_family);
 528 #endif  /* _NET_FIB_H */

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