linux/include/net/ip_fib.h
<<
>>
Prefs
   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_rules.h>
  23#include <net/inetpeer.h>
  24#include <linux/percpu.h>
  25
  26struct fib_config {
  27        u8                      fc_dst_len;
  28        u8                      fc_tos;
  29        u8                      fc_protocol;
  30        u8                      fc_scope;
  31        u8                      fc_type;
  32        /* 3 bytes unused */
  33        u32                     fc_table;
  34        __be32                  fc_dst;
  35        __be32                  fc_gw;
  36        int                     fc_oif;
  37        u32                     fc_flags;
  38        u32                     fc_priority;
  39        __be32                  fc_prefsrc;
  40        struct nlattr           *fc_mx;
  41        struct rtnexthop        *fc_mp;
  42        int                     fc_mx_len;
  43        int                     fc_mp_len;
  44        u32                     fc_flow;
  45        u32                     fc_nlflags;
  46        struct nl_info          fc_nlinfo;
  47 };
  48
  49struct fib_info;
  50struct rtable;
  51
  52struct fib_nh_exception {
  53        struct fib_nh_exception __rcu   *fnhe_next;
  54        __be32                          fnhe_daddr;
  55        u32                             fnhe_pmtu;
  56        __be32                          fnhe_gw;
  57        unsigned long                   fnhe_expires;
  58        struct rtable __rcu             *fnhe_rth;
  59        unsigned long                   fnhe_stamp;
  60};
  61
  62struct fnhe_hash_bucket {
  63        struct fib_nh_exception __rcu   *chain;
  64};
  65
  66#define FNHE_HASH_SIZE          2048
  67#define FNHE_RECLAIM_DEPTH      5
  68
  69struct fib_nh {
  70        struct net_device       *nh_dev;
  71        struct hlist_node       nh_hash;
  72        struct fib_info         *nh_parent;
  73        unsigned int            nh_flags;
  74        unsigned char           nh_scope;
  75#ifdef CONFIG_IP_ROUTE_MULTIPATH
  76        int                     nh_weight;
  77        int                     nh_power;
  78#endif
  79#ifdef CONFIG_IP_ROUTE_CLASSID
  80        __u32                   nh_tclassid;
  81#endif
  82        int                     nh_oif;
  83        __be32                  nh_gw;
  84        __be32                  nh_saddr;
  85        int                     nh_saddr_genid;
  86        struct rtable __rcu * __percpu *nh_pcpu_rth_output;
  87        struct rtable __rcu     *nh_rth_input;
  88        struct fnhe_hash_bucket *nh_exceptions;
  89};
  90
  91/*
  92 * This structure contains data shared by many of routes.
  93 */
  94
  95struct fib_info {
  96        struct hlist_node       fib_hash;
  97        struct hlist_node       fib_lhash;
  98        struct net              *fib_net;
  99        int                     fib_treeref;
 100        atomic_t                fib_clntref;
 101        unsigned int            fib_flags;
 102        unsigned char           fib_dead;
 103        unsigned char           fib_protocol;
 104        unsigned char           fib_scope;
 105        unsigned char           fib_type;
 106        __be32                  fib_prefsrc;
 107        u32                     fib_priority;
 108        u32                     *fib_metrics;
 109#define fib_mtu fib_metrics[RTAX_MTU-1]
 110#define fib_window fib_metrics[RTAX_WINDOW-1]
 111#define fib_rtt fib_metrics[RTAX_RTT-1]
 112#define fib_advmss fib_metrics[RTAX_ADVMSS-1]
 113        int                     fib_nhs;
 114#ifdef CONFIG_IP_ROUTE_MULTIPATH
 115        int                     fib_power;
 116#endif
 117        struct rcu_head         rcu;
 118        struct fib_nh           fib_nh[0];
 119#define fib_dev         fib_nh[0].nh_dev
 120};
 121
 122
 123#ifdef CONFIG_IP_MULTIPLE_TABLES
 124struct fib_rule;
 125#endif
 126
 127struct fib_table;
 128struct fib_result {
 129        unsigned char   prefixlen;
 130        unsigned char   nh_sel;
 131        unsigned char   type;
 132        unsigned char   scope;
 133        u32             tclassid;
 134        struct fib_info *fi;
 135        struct fib_table *table;
 136        struct list_head *fa_head;
 137};
 138
 139struct fib_result_nl {
 140        __be32          fl_addr;   /* To be looked up*/
 141        u32             fl_mark;
 142        unsigned char   fl_tos;
 143        unsigned char   fl_scope;
 144        unsigned char   tb_id_in;
 145
 146        unsigned char   tb_id;      /* Results */
 147        unsigned char   prefixlen;
 148        unsigned char   nh_sel;
 149        unsigned char   type;
 150        unsigned char   scope;
 151        int             err;      
 152};
 153
 154#ifdef CONFIG_IP_ROUTE_MULTIPATH
 155
 156#define FIB_RES_NH(res)         ((res).fi->fib_nh[(res).nh_sel])
 157
 158#define FIB_TABLE_HASHSZ 2
 159
 160#else /* CONFIG_IP_ROUTE_MULTIPATH */
 161
 162#define FIB_RES_NH(res)         ((res).fi->fib_nh[0])
 163
 164#define FIB_TABLE_HASHSZ 256
 165
 166#endif /* CONFIG_IP_ROUTE_MULTIPATH */
 167
 168extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
 169
 170#define FIB_RES_SADDR(net, res)                         \
 171        ((FIB_RES_NH(res).nh_saddr_genid ==             \
 172          atomic_read(&(net)->ipv4.dev_addr_genid)) ?   \
 173         FIB_RES_NH(res).nh_saddr :                     \
 174         fib_info_update_nh_saddr((net), &FIB_RES_NH(res)))
 175#define FIB_RES_GW(res)                 (FIB_RES_NH(res).nh_gw)
 176#define FIB_RES_DEV(res)                (FIB_RES_NH(res).nh_dev)
 177#define FIB_RES_OIF(res)                (FIB_RES_NH(res).nh_oif)
 178
 179#define FIB_RES_PREFSRC(net, res)       ((res).fi->fib_prefsrc ? : \
 180                                         FIB_RES_SADDR(net, res))
 181
 182struct fib_table {
 183        struct hlist_node       tb_hlist;
 184        u32                     tb_id;
 185        int                     tb_default;
 186        int                     tb_num_default;
 187        unsigned long           tb_data[0];
 188};
 189
 190extern int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
 191                            struct fib_result *res, int fib_flags);
 192extern int fib_table_insert(struct fib_table *, struct fib_config *);
 193extern int fib_table_delete(struct fib_table *, struct fib_config *);
 194extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
 195                          struct netlink_callback *cb);
 196extern int fib_table_flush(struct fib_table *table);
 197extern void fib_free_table(struct fib_table *tb);
 198
 199
 200
 201#ifndef CONFIG_IP_MULTIPLE_TABLES
 202
 203#define TABLE_LOCAL_INDEX       0
 204#define TABLE_MAIN_INDEX        1
 205
 206static inline struct fib_table *fib_get_table(struct net *net, u32 id)
 207{
 208        struct hlist_head *ptr;
 209
 210        ptr = id == RT_TABLE_LOCAL ?
 211                &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] :
 212                &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
 213        return hlist_entry(ptr->first, struct fib_table, tb_hlist);
 214}
 215
 216static inline struct fib_table *fib_new_table(struct net *net, u32 id)
 217{
 218        return fib_get_table(net, id);
 219}
 220
 221static inline int fib_lookup(struct net *net, const struct flowi4 *flp,
 222                             struct fib_result *res)
 223{
 224        struct fib_table *table;
 225
 226        table = fib_get_table(net, RT_TABLE_LOCAL);
 227        if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
 228                return 0;
 229
 230        table = fib_get_table(net, RT_TABLE_MAIN);
 231        if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
 232                return 0;
 233        return -ENETUNREACH;
 234}
 235
 236#else /* CONFIG_IP_MULTIPLE_TABLES */
 237extern int __net_init fib4_rules_init(struct net *net);
 238extern void __net_exit fib4_rules_exit(struct net *net);
 239
 240extern struct fib_table *fib_new_table(struct net *net, u32 id);
 241extern struct fib_table *fib_get_table(struct net *net, u32 id);
 242
 243extern int __fib_lookup(struct net *net, struct flowi4 *flp,
 244                        struct fib_result *res);
 245
 246static inline int fib_lookup(struct net *net, struct flowi4 *flp,
 247                             struct fib_result *res)
 248{
 249        if (!net->ipv4.fib_has_custom_rules) {
 250                res->tclassid = 0;
 251                if (net->ipv4.fib_local &&
 252                    !fib_table_lookup(net->ipv4.fib_local, flp, res,
 253                                      FIB_LOOKUP_NOREF))
 254                        return 0;
 255                if (net->ipv4.fib_main &&
 256                    !fib_table_lookup(net->ipv4.fib_main, flp, res,
 257                                      FIB_LOOKUP_NOREF))
 258                        return 0;
 259                if (net->ipv4.fib_default &&
 260                    !fib_table_lookup(net->ipv4.fib_default, flp, res,
 261                                      FIB_LOOKUP_NOREF))
 262                        return 0;
 263                return -ENETUNREACH;
 264        }
 265        return __fib_lookup(net, flp, res);
 266}
 267
 268#endif /* CONFIG_IP_MULTIPLE_TABLES */
 269
 270/* Exported by fib_frontend.c */
 271extern const struct nla_policy rtm_ipv4_policy[];
 272extern void             ip_fib_init(void);
 273extern __be32 fib_compute_spec_dst(struct sk_buff *skb);
 274extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
 275                               u8 tos, int oif, struct net_device *dev,
 276                               struct in_device *idev, u32 *itag);
 277extern void fib_select_default(struct fib_result *res);
 278#ifdef CONFIG_IP_ROUTE_CLASSID
 279static inline int fib_num_tclassid_users(struct net *net)
 280{
 281        return net->ipv4.fib_num_tclassid_users;
 282}
 283#else
 284static inline int fib_num_tclassid_users(struct net *net)
 285{
 286        return 0;
 287}
 288#endif
 289
 290/* Exported by fib_semantics.c */
 291extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
 292extern int fib_sync_down_dev(struct net_device *dev, int force);
 293extern int fib_sync_down_addr(struct net *net, __be32 local);
 294extern void fib_update_nh_saddrs(struct net_device *dev);
 295extern int fib_sync_up(struct net_device *dev);
 296extern void fib_select_multipath(struct fib_result *res);
 297
 298/* Exported by fib_trie.c */
 299extern void fib_trie_init(void);
 300extern struct fib_table *fib_trie_table(u32 id);
 301
 302static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
 303{
 304#ifdef CONFIG_IP_ROUTE_CLASSID
 305#ifdef CONFIG_IP_MULTIPLE_TABLES
 306        u32 rtag;
 307#endif
 308        *itag = FIB_RES_NH(*res).nh_tclassid<<16;
 309#ifdef CONFIG_IP_MULTIPLE_TABLES
 310        rtag = res->tclassid;
 311        if (*itag == 0)
 312                *itag = (rtag<<16);
 313        *itag |= (rtag>>16);
 314#endif
 315#endif
 316}
 317
 318extern void free_fib_info(struct fib_info *fi);
 319
 320static inline void fib_info_put(struct fib_info *fi)
 321{
 322        if (atomic_dec_and_test(&fi->fib_clntref))
 323                free_fib_info(fi);
 324}
 325
 326#ifdef CONFIG_PROC_FS
 327extern int __net_init  fib_proc_init(struct net *net);
 328extern void __net_exit fib_proc_exit(struct net *net);
 329#else
 330static inline int fib_proc_init(struct net *net)
 331{
 332        return 0;
 333}
 334static inline void fib_proc_exit(struct net *net)
 335{
 336}
 337#endif
 338
 339#endif  /* _NET_FIB_H */
 340
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.