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};
  55
  56struct fib6_node {
  57        struct fib6_node        *parent;
  58        struct fib6_node        *left;
  59        struct fib6_node        *right;
  60#ifdef CONFIG_IPV6_SUBTREES
  61        struct fib6_node        *subtree;
  62#endif
  63        struct rt6_info         *leaf;
  64
  65        __u16                   fn_bit;         /* bit key */
  66        __u16                   fn_flags;
  67        int                     fn_sernum;
  68        struct rt6_info         *rr_ptr;
  69};
  70
  71#ifndef CONFIG_IPV6_SUBTREES
  72#define FIB6_SUBTREE(fn)        NULL
  73#else
  74#define FIB6_SUBTREE(fn)        ((fn)->subtree)
  75#endif
  76
  77struct mx6_config {
  78        const u32 *mx;
  79        DECLARE_BITMAP(mx_valid, RTAX_MAX);
  80};
  81
  82/*
  83 *      routing information
  84 *
  85 */
  86
  87struct rt6key {
  88        struct in6_addr addr;
  89        int             plen;
  90};
  91
  92struct fib6_table;
  93
  94struct rt6_info {
  95        struct dst_entry                dst;
  96
  97        /*
  98         * Tail elements of dst_entry (__refcnt etc.)
  99         * and these elements (rarely used in hot path) are in
 100         * the same cache line.
 101         */
 102        struct fib6_table               *rt6i_table;
 103        struct fib6_node                *rt6i_node;
 104
 105        struct in6_addr                 rt6i_gateway;
 106
 107        /* Multipath routes:
 108         * siblings is a list of rt6_info that have the the same metric/weight,
 109         * destination, but not the same gateway. nsiblings is just a cache
 110         * to speed up lookup.
 111         */
 112        struct list_head                rt6i_siblings;
 113        unsigned int                    rt6i_nsiblings;
 114
 115        atomic_t                        rt6i_ref;
 116
 117        /* These are in a separate cache line. */
 118        struct rt6key                   rt6i_dst ____cacheline_aligned_in_smp;
 119        u32                             rt6i_flags;
 120        struct rt6key                   rt6i_src;
 121        struct rt6key                   rt6i_prefsrc;
 122
 123        struct inet6_dev                *rt6i_idev;
 124        unsigned long                   _rt6i_peer;
 125
 126        u32                             rt6i_metric;
 127        /* more non-fragment space at head required */
 128        unsigned short                  rt6i_nfheader_len;
 129        u8                              rt6i_protocol;
 130};
 131
 132static inline struct inet_peer *rt6_peer_ptr(struct rt6_info *rt)
 133{
 134        return inetpeer_ptr(rt->_rt6i_peer);
 135}
 136
 137static inline bool rt6_has_peer(struct rt6_info *rt)
 138{
 139        return inetpeer_ptr_is_peer(rt->_rt6i_peer);
 140}
 141
 142static inline void __rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
 143{
 144        __inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
 145}
 146
 147static inline bool rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
 148{
 149        return inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
 150}
 151
 152static inline void rt6_init_peer(struct rt6_info *rt, struct inet_peer_base *base)
 153{
 154        inetpeer_init_ptr(&rt->_rt6i_peer, base);
 155}
 156
 157static inline void rt6_transfer_peer(struct rt6_info *rt, struct rt6_info *ort)
 158{
 159        inetpeer_transfer_peer(&rt->_rt6i_peer, &ort->_rt6i_peer);
 160}
 161
 162static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
 163{
 164        return ((struct rt6_info *)dst)->rt6i_idev;
 165}
 166
 167static inline void rt6_clean_expires(struct rt6_info *rt)
 168{
 169        rt->rt6i_flags &= ~RTF_EXPIRES;
 170        rt->dst.expires = 0;
 171}
 172
 173static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
 174{
 175        rt->dst.expires = expires;
 176        rt->rt6i_flags |= RTF_EXPIRES;
 177}
 178
 179static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
 180{
 181        struct rt6_info *rt;
 182
 183        for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES);
 184             rt = (struct rt6_info *)rt->dst.from);
 185        if (rt && rt != rt0)
 186                rt0->dst.expires = rt->dst.expires;
 187
 188        dst_set_expires(&rt0->dst, timeout);
 189        rt0->rt6i_flags |= RTF_EXPIRES;
 190}
 191
 192static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
 193{
 194        struct dst_entry *new = (struct dst_entry *) from;
 195
 196        rt->rt6i_flags &= ~RTF_EXPIRES;
 197        dst_hold(new);
 198        rt->dst.from = new;
 199}
 200
 201static inline void ip6_rt_put(struct rt6_info *rt)
 202{
 203        /* dst_release() accepts a NULL parameter.
 204         * We rely on dst being first structure in struct rt6_info
 205         */
 206        BUILD_BUG_ON(offsetof(struct rt6_info, dst) != 0);
 207        dst_release(&rt->dst);
 208}
 209
 210enum fib6_walk_state {
 211#ifdef CONFIG_IPV6_SUBTREES
 212        FWS_S,
 213#endif
 214        FWS_L,
 215        FWS_R,
 216        FWS_C,
 217        FWS_U
 218};
 219
 220struct fib6_walker {
 221        struct list_head lh;
 222        struct fib6_node *root, *node;
 223        struct rt6_info *leaf;
 224        enum fib6_walk_state state;
 225        bool prune;
 226        unsigned int skip;
 227        unsigned int count;
 228        int (*func)(struct fib6_walker *);
 229        void *args;
 230};
 231
 232struct rt6_statistics {
 233        __u32           fib_nodes;
 234        __u32           fib_route_nodes;
 235        __u32           fib_rt_alloc;           /* permanent routes     */
 236        __u32           fib_rt_entries;         /* rt entries in table  */
 237        __u32           fib_rt_cache;           /* cache routes         */
 238        __u32           fib_discarded_routes;
 239};
 240
 241#define RTN_TL_ROOT     0x0001
 242#define RTN_ROOT        0x0002          /* tree root node               */
 243#define RTN_RTINFO      0x0004          /* node with valid routing info */
 244
 245/*
 246 *      priority levels (or metrics)
 247 *
 248 */
 249
 250
 251struct fib6_table {
 252        struct hlist_node       tb6_hlist;
 253        u32                     tb6_id;
 254        rwlock_t                tb6_lock;
 255        struct fib6_node        tb6_root;
 256        struct inet_peer_base   tb6_peers;
 257};
 258
 259#define RT6_TABLE_UNSPEC        RT_TABLE_UNSPEC
 260#define RT6_TABLE_MAIN          RT_TABLE_MAIN
 261#define RT6_TABLE_DFLT          RT6_TABLE_MAIN
 262#define RT6_TABLE_INFO          RT6_TABLE_MAIN
 263#define RT6_TABLE_PREFIX        RT6_TABLE_MAIN
 264
 265#ifdef CONFIG_IPV6_MULTIPLE_TABLES
 266#define FIB6_TABLE_MIN          1
 267#define FIB6_TABLE_MAX          RT_TABLE_MAX
 268#define RT6_TABLE_LOCAL         RT_TABLE_LOCAL
 269#else
 270#define FIB6_TABLE_MIN          RT_TABLE_MAIN
 271#define FIB6_TABLE_MAX          FIB6_TABLE_MIN
 272#define RT6_TABLE_LOCAL         RT6_TABLE_MAIN
 273#endif
 274
 275typedef struct rt6_info *(*pol_lookup_t)(struct net *,
 276                                         struct fib6_table *,
 277                                         struct flowi6 *, int);
 278
 279/*
 280 *      exported functions
 281 */
 282
 283struct fib6_table *fib6_get_table(struct net *net, u32 id);
 284struct fib6_table *fib6_new_table(struct net *net, u32 id);
 285struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
 286                                   int flags, pol_lookup_t lookup);
 287
 288struct fib6_node *fib6_lookup(struct fib6_node *root,
 289                              const struct in6_addr *daddr,
 290                              const struct in6_addr *saddr);
 291
 292struct fib6_node *fib6_locate(struct fib6_node *root,
 293                              const struct in6_addr *daddr, int dst_len,
 294                              const struct in6_addr *saddr, int src_len);
 295
 296void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
 297                    void *arg);
 298
 299int fib6_add(struct fib6_node *root, struct rt6_info *rt,
 300             struct nl_info *info, struct mx6_config *mxc);
 301int fib6_del(struct rt6_info *rt, struct nl_info *info);
 302
 303void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info);
 304
 305void fib6_run_gc(unsigned long expires, struct net *net, bool force);
 306
 307void fib6_gc_cleanup(void);
 308
 309int fib6_init(void);
 310
 311int ipv6_route_open(struct inode *inode, struct file *file);
 312
 313#ifdef CONFIG_IPV6_MULTIPLE_TABLES
 314int fib6_rules_init(void);
 315void fib6_rules_cleanup(void);
 316#else
 317static inline int               fib6_rules_init(void)
 318{
 319        return 0;
 320}
 321static inline void              fib6_rules_cleanup(void)
 322{
 323        return ;
 324}
 325#endif
 326#endif
 327