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