linux/include/net/ip6_fib.h
<<
>>
Prefs
   1/*
   2 *      Linux INET6 implementation 
   3 *
   4 *      Authors:
   5 *      Pedro Roque             <roque@di.fc.ul.pt>     
   6 *
   7 *      This program is free software; you can redistribute it and/or
   8 *      modify it under the terms of the GNU General Public License
   9 *      as published by the Free Software Foundation; either version
  10 *      2 of the License, or (at your option) any later version.
  11 */
  12
  13#ifndef _IP6_FIB_H
  14#define _IP6_FIB_H
  15
  16#include <linux/ipv6_route.h>
  17#include <linux/rtnetlink.h>
  18#include <linux/spinlock.h>
  19#include <net/dst.h>
  20#include <net/flow.h>
  21#include <net/netlink.h>
  22#include <net/inetpeer.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
  30struct rt6_info;
  31
  32struct fib6_config {
  33        u32             fc_table;
  34        u32             fc_metric;
  35        int             fc_dst_len;
  36        int             fc_src_len;
  37        int             fc_ifindex;
  38        u32             fc_flags;
  39        u32             fc_protocol;
  40        u32             fc_type;        /* only 8 bits are used */
  41
  42        struct in6_addr fc_dst;
  43        struct in6_addr fc_src;
  44        struct in6_addr fc_prefsrc;
  45        struct in6_addr fc_gateway;
  46
  47        unsigned long   fc_expires;
  48        struct nlattr   *fc_mx;
  49        int             fc_mx_len;
  50        int             fc_mp_len;
  51        struct nlattr   *fc_mp;
  52
  53        struct nl_info  fc_nlinfo;
  54        struct nlattr   *fc_encap;
  55        u16             fc_encap_type;
  56};
  57
  58struct fib6_node {
  59        struct fib6_node        *parent;
  60        struct fib6_node        *left;
  61        struct fib6_node        *right;
  62#ifdef CONFIG_IPV6_SUBTREES
  63        struct fib6_node        *subtree;
  64#endif
  65        struct rt6_info         *leaf;
  66
  67        __u16                   fn_bit;         /* bit key */
  68        __u16                   fn_flags;
  69        int                     fn_sernum;
  70        struct rt6_info         *rr_ptr;
  71};
  72
  73#ifndef CONFIG_IPV6_SUBTREES
  74#define FIB6_SUBTREE(fn)        NULL
  75#else
  76#define FIB6_SUBTREE(fn)        ((fn)->subtree)
  77#endif
  78
  79struct mx6_config {
  80        const u32 *mx;
  81        DECLARE_BITMAP(mx_valid, RTAX_MAX);
  82};
  83
  84/*
  85 *      routing information
  86 *
  87 */
  88
  89struct rt6key {
  90        struct in6_addr addr;
  91        int             plen;
  92};
  93
  94struct fib6_table;
  95
  96struct rt6_info {
  97        struct dst_entry                dst;
  98
  99        /*
 100         * Tail elements of dst_entry (__refcnt etc.)
 101         * and these elements (rarely used in hot path) are in
 102         * the same cache line.
 103         */
 104        struct fib6_table               *rt6i_table;
 105        struct fib6_node                *rt6i_node;
 106
 107        struct in6_addr                 rt6i_gateway;
 108
 109        /* Multipath routes:
 110         * siblings is a list of rt6_info that have the the same metric/weight,
 111         * destination, but not the same gateway. nsiblings is just a cache
 112         * to speed up lookup.
 113         */
 114        struct list_head                rt6i_siblings;
 115        unsigned int                    rt6i_nsiblings;
 116
 117        atomic_t                        rt6i_ref;
 118
 119        /* These are in a separate cache line. */
 120        struct rt6key                   rt6i_dst ____cacheline_aligned_in_smp;
 121        u32                             rt6i_flags;
 122        struct rt6key                   rt6i_src;
 123        struct rt6key                   rt6i_prefsrc;
 124
 125        struct list_head                rt6i_uncached;
 126        struct uncached_list            *rt6i_uncached_list;
 127
 128        struct inet6_dev                *rt6i_idev;
 129        struct rt6_info * __percpu      *rt6i_pcpu;
 130
 131        u32                             rt6i_metric;
 132        u32                             rt6i_pmtu;
 133        /* more non-fragment space at head required */
 134        unsigned short                  rt6i_nfheader_len;
 135        u8                              rt6i_protocol;
 136};
 137
 138static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
 139{
 140        return ((struct rt6_info *)dst)->rt6i_idev;
 141}
 142
 143static inline void rt6_clean_expires(struct rt6_info *rt)
 144{
 145        rt->rt6i_flags &= ~RTF_EXPIRES;
 146        rt->dst.expires = 0;
 147}
 148
 149static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
 150{
 151        rt->dst.expires = expires;
 152        rt->rt6i_flags |= RTF_EXPIRES;
 153}
 154
 155static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
 156{
 157        struct rt6_info *rt;
 158
 159        for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES);
 160             rt = (struct rt6_info *)rt->dst.from);
 161        if (rt && rt != rt0)
 162                rt0->dst.expires = rt->dst.expires;
 163
 164        dst_set_expires(&rt0->dst, timeout);
 165        rt0->rt6i_flags |= RTF_EXPIRES;
 166}
 167
 168static inline u32 rt6_get_cookie(const struct rt6_info *rt)
 169{
 170        if (rt->rt6i_flags & RTF_PCPU ||
 171            (unlikely(rt->dst.flags & DST_NOCACHE) && rt->dst.from))
 172                rt = (struct rt6_info *)(rt->dst.from);
 173
 174        return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
 175}
 176
 177static inline void ip6_rt_put(struct rt6_info *rt)
 178{
 179        /* dst_release() accepts a NULL parameter.
 180         * We rely on dst being first structure in struct rt6_info
 181         */
 182        BUILD_BUG_ON(offsetof(struct rt6_info, dst) != 0);
 183        dst_release(&rt->dst);
 184}
 185
 186enum fib6_walk_state {
 187#ifdef CONFIG_IPV6_SUBTREES
 188        FWS_S,
 189#endif
 190        FWS_L,
 191        FWS_R,
 192        FWS_C,
 193        FWS_U
 194};
 195
 196struct fib6_walker {
 197        struct list_head lh;
 198        struct fib6_node *root, *node;
 199        struct rt6_info *leaf;
 200        enum fib6_walk_state state;
 201        bool prune;
 202        unsigned int skip;
 203        unsigned int count;
 204        int (*func)(struct fib6_walker *);
 205        void *args;
 206};
 207
 208struct rt6_statistics {
 209        __u32           fib_nodes;
 210        __u32           fib_route_nodes;
 211        __u32           fib_rt_alloc;           /* permanent routes     */
 212        __u32           fib_rt_entries;         /* rt entries in table  */
 213        __u32           fib_rt_cache;           /* cache routes         */
 214        __u32           fib_discarded_routes;
 215};
 216
 217#define RTN_TL_ROOT     0x0001
 218#define RTN_ROOT        0x0002          /* tree root node               */
 219#define RTN_RTINFO      0x0004          /* node with valid routing info */
 220
 221/*
 222 *      priority levels (or metrics)
 223 *
 224 */
 225
 226
 227struct fib6_table {
 228        struct hlist_node       tb6_hlist;
 229        u32                     tb6_id;
 230        rwlock_t                tb6_lock;
 231        struct fib6_node        tb6_root;
 232        struct inet_peer_base   tb6_peers;
 233        unsigned int            flags;
 234#define RT6_TABLE_HAS_DFLT_ROUTER       BIT(0)
 235};
 236
 237#define RT6_TABLE_UNSPEC        RT_TABLE_UNSPEC
 238#define RT6_TABLE_MAIN          RT_TABLE_MAIN
 239#define RT6_TABLE_DFLT          RT6_TABLE_MAIN
 240#define RT6_TABLE_INFO          RT6_TABLE_MAIN
 241#define RT6_TABLE_PREFIX        RT6_TABLE_MAIN
 242
 243#ifdef CONFIG_IPV6_MULTIPLE_TABLES
 244#define FIB6_TABLE_MIN          1
 245#define FIB6_TABLE_MAX          RT_TABLE_MAX
 246#define RT6_TABLE_LOCAL         RT_TABLE_LOCAL
 247#else
 248#define FIB6_TABLE_MIN          RT_TABLE_MAIN
 249#define FIB6_TABLE_MAX          FIB6_TABLE_MIN
 250#define RT6_TABLE_LOCAL         RT6_TABLE_MAIN
 251#endif
 252
 253typedef struct rt6_info *(*pol_lookup_t)(struct net *,
 254                                         struct fib6_table *,
 255                                         struct flowi6 *, int);
 256
 257/*
 258 *      exported functions
 259 */
 260
 261struct fib6_table *fib6_get_table(struct net *net, u32 id);
 262struct fib6_table *fib6_new_table(struct net *net, u32 id);
 263struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
 264                                   int flags, pol_lookup_t lookup);
 265
 266struct fib6_node *fib6_lookup(struct fib6_node *root,
 267                              const struct in6_addr *daddr,
 268                              const struct in6_addr *saddr);
 269
 270struct fib6_node *fib6_locate(struct fib6_node *root,
 271                              const struct in6_addr *daddr, int dst_len,
 272                              const struct in6_addr *saddr, int src_len);
 273
 274void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
 275                    void *arg);
 276
 277int fib6_add(struct fib6_node *root, struct rt6_info *rt,
 278             struct nl_info *info, struct mx6_config *mxc);
 279int fib6_del(struct rt6_info *rt, struct nl_info *info);
 280
 281void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
 282                     unsigned int flags);
 283
 284void fib6_run_gc(unsigned long expires, struct net *net, bool force);
 285
 286void fib6_gc_cleanup(void);
 287
 288int fib6_init(void);
 289
 290int ipv6_route_open(struct inode *inode, struct file *file);
 291
 292#ifdef CONFIG_IPV6_MULTIPLE_TABLES
 293int fib6_rules_init(void);
 294void fib6_rules_cleanup(void);
 295#else
 296static inline int               fib6_rules_init(void)
 297{
 298        return 0;
 299}
 300static inline void              fib6_rules_cleanup(void)
 301{
 302        return ;
 303}
 304#endif
 305#endif
 306