Annotation of embedaddon/bird2/nest/route.h, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     BIRD Internet Routing Daemon -- Routing Table
        !             3:  *
        !             4:  *     (c) 1998--2000 Martin Mares <mj@ucw.cz>
        !             5:  *
        !             6:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             7:  */
        !             8: 
        !             9: #ifndef _BIRD_ROUTE_H_
        !            10: #define _BIRD_ROUTE_H_
        !            11: 
        !            12: #include "lib/lists.h"
        !            13: #include "lib/resource.h"
        !            14: #include "lib/net.h"
        !            15: 
        !            16: struct ea_list;
        !            17: struct protocol;
        !            18: struct proto;
        !            19: struct rte_src;
        !            20: struct symbol;
        !            21: struct filter;
        !            22: struct cli;
        !            23: 
        !            24: /*
        !            25:  *     Generic data structure for storing network prefixes. Also used
        !            26:  *     for the master routing table. Currently implemented as a hash
        !            27:  *     table.
        !            28:  *
        !            29:  *     Available operations:
        !            30:  *             - insertion of new entry
        !            31:  *             - deletion of entry
        !            32:  *             - searching for entry by network prefix
        !            33:  *             - asynchronous retrieval of fib contents
        !            34:  */
        !            35: 
        !            36: struct fib_node {
        !            37:   struct fib_node *next;               /* Next in hash chain */
        !            38:   struct fib_iterator *readers;                /* List of readers of this node */
        !            39:   byte flags;                          /* User-defined, will be removed */
        !            40:   net_addr addr[0];
        !            41: };
        !            42: 
        !            43: struct fib_iterator {                  /* See lib/slists.h for an explanation */
        !            44:   struct fib_iterator *prev, *next;    /* Must be synced with struct fib_node! */
        !            45:   byte efef;                           /* 0xff to distinguish between iterator and node */
        !            46:   byte pad[3];
        !            47:   struct fib_node *node;               /* Or NULL if freshly merged */
        !            48:   uint hash;
        !            49: };
        !            50: 
        !            51: typedef void (*fib_init_fn)(void *);
        !            52: 
        !            53: struct fib {
        !            54:   pool *fib_pool;                      /* Pool holding all our data */
        !            55:   slab *fib_slab;                      /* Slab holding all fib nodes */
        !            56:   struct fib_node **hash_table;                /* Node hash table */
        !            57:   uint hash_size;                      /* Number of hash table entries (a power of two) */
        !            58:   uint hash_order;                     /* Binary logarithm of hash_size */
        !            59:   uint hash_shift;                     /* 32 - hash_order */
        !            60:   uint addr_type;                      /* Type of address data stored in fib (NET_*) */
        !            61:   uint node_size;                      /* FIB node size, 0 for nonuniform */
        !            62:   uint node_offset;                    /* Offset of fib_node struct inside of user data */
        !            63:   uint entries;                                /* Number of entries */
        !            64:   uint entries_min, entries_max;       /* Entry count limits (else start rehashing) */
        !            65:   fib_init_fn init;                    /* Constructor */
        !            66: };
        !            67: 
        !            68: static inline void * fib_node_to_user(struct fib *f, struct fib_node *e)
        !            69: { return e ? (void *) ((char *) e - f->node_offset) : NULL; }
        !            70: 
        !            71: static inline struct fib_node * fib_user_to_node(struct fib *f, void *e)
        !            72: { return e ? (void *) ((char *) e + f->node_offset) : NULL; }
        !            73: 
        !            74: void fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init);
        !            75: void *fib_find(struct fib *, const net_addr *);        /* Find or return NULL if doesn't exist */
        !            76: void *fib_get_chain(struct fib *f, const net_addr *a); /* Find first node in linked list from hash table */
        !            77: void *fib_get(struct fib *, const net_addr *); /* Find or create new if nonexistent */
        !            78: void *fib_route(struct fib *, const net_addr *); /* Longest-match routing lookup */
        !            79: void fib_delete(struct fib *, void *); /* Remove fib entry */
        !            80: void fib_free(struct fib *);           /* Destroy the fib */
        !            81: void fib_check(struct fib *);          /* Consistency check for debugging */
        !            82: 
        !            83: void fit_init(struct fib_iterator *, struct fib *); /* Internal functions, don't call */
        !            84: struct fib_node *fit_get(struct fib *, struct fib_iterator *);
        !            85: void fit_put(struct fib_iterator *, struct fib_node *);
        !            86: void fit_put_next(struct fib *f, struct fib_iterator *i, struct fib_node *n, uint hpos);
        !            87: 
        !            88: 
        !            89: #define FIB_WALK(fib, type, z) do {                            \
        !            90:        struct fib_node *fn_, **ff_ = (fib)->hash_table;        \
        !            91:        uint count_ = (fib)->hash_size;                         \
        !            92:        type *z;                                                \
        !            93:        while (count_--)                                        \
        !            94:          for (fn_ = *ff_++; z = fib_node_to_user(fib, fn_); fn_=fn_->next)
        !            95: 
        !            96: #define FIB_WALK_END } while (0)
        !            97: 
        !            98: #define FIB_ITERATE_INIT(it, fib) fit_init(it, fib)
        !            99: 
        !           100: #define FIB_ITERATE_START(fib, it, type, z) do {               \
        !           101:        struct fib_node *fn_ = fit_get(fib, it);                \
        !           102:        uint count_ = (fib)->hash_size;                         \
        !           103:        uint hpos_ = (it)->hash;                                \
        !           104:        type *z;                                                \
        !           105:        for(;;) {                                               \
        !           106:          if (!fn_)                                             \
        !           107:            {                                                   \
        !           108:               if (++hpos_ >= count_)                           \
        !           109:                 break;                                         \
        !           110:               fn_ = (fib)->hash_table[hpos_];                  \
        !           111:               continue;                                        \
        !           112:            }                                                   \
        !           113:          z = fib_node_to_user(fib, fn_);
        !           114: 
        !           115: #define FIB_ITERATE_END fn_ = fn_->next; } } while(0)
        !           116: 
        !           117: #define FIB_ITERATE_PUT(it) fit_put(it, fn_)
        !           118: 
        !           119: #define FIB_ITERATE_PUT_NEXT(it, fib) fit_put_next(fib, it, fn_, hpos_)
        !           120: 
        !           121: #define FIB_ITERATE_UNLINK(it, fib) fit_get(fib, it)
        !           122: 
        !           123: 
        !           124: /*
        !           125:  *     Master Routing Tables. Generally speaking, each of them contains a FIB
        !           126:  *     with each entry pointing to a list of route entries representing routes
        !           127:  *     to given network (with the selected one at the head).
        !           128:  *
        !           129:  *     Each of the RTE's contains variable data (the preference and protocol-dependent
        !           130:  *     metrics) and a pointer to a route attribute block common for many routes).
        !           131:  *
        !           132:  *     It's guaranteed that there is at most one RTE for every (prefix,proto) pair.
        !           133:  */
        !           134: 
        !           135: struct rtable_config {
        !           136:   node n;
        !           137:   char *name;
        !           138:   struct rtable *table;
        !           139:   struct proto_config *krt_attached;   /* Kernel syncer attached to this table */
        !           140:   uint addr_type;                      /* Type of address data stored in table (NET_*) */
        !           141:   int gc_max_ops;                      /* Maximum number of operations before GC is run */
        !           142:   int gc_min_time;                     /* Minimum time between two consecutive GC runs */
        !           143:   byte sorted;                         /* Routes of network are sorted according to rte_better() */
        !           144: };
        !           145: 
        !           146: typedef struct rtable {
        !           147:   node n;                              /* Node in list of all tables */
        !           148:   struct fib fib;
        !           149:   char *name;                          /* Name of this table */
        !           150:   list channels;                       /* List of attached channels (struct channel) */
        !           151:   uint addr_type;                      /* Type of address data stored in table (NET_*) */
        !           152:   int pipe_busy;                       /* Pipe loop detection */
        !           153:   int use_count;                       /* Number of protocols using this table */
        !           154:   u32 rt_count;                                /* Number of routes in the table */
        !           155:   struct hostcache *hostcache;
        !           156:   struct rtable_config *config;                /* Configuration of this table */
        !           157:   struct config *deleted;              /* Table doesn't exist in current configuration,
        !           158:                                         * delete as soon as use_count becomes 0 and remove
        !           159:                                         * obstacle from this routing table.
        !           160:                                         */
        !           161:   struct event *rt_event;              /* Routing table event */
        !           162:   btime gc_time;                       /* Time of last GC */
        !           163:   int gc_counter;                      /* Number of operations since last GC */
        !           164:   byte prune_state;                    /* Table prune state, 1 -> scheduled, 2-> running */
        !           165:   byte hcu_scheduled;                  /* Hostcache update is scheduled */
        !           166:   byte nhu_state;                      /* Next Hop Update state */
        !           167:   struct fib_iterator prune_fit;       /* Rtable prune FIB iterator */
        !           168:   struct fib_iterator nhu_fit;         /* Next Hop Update FIB iterator */
        !           169: } rtable;
        !           170: 
        !           171: #define NHU_CLEAN      0
        !           172: #define NHU_SCHEDULED  1
        !           173: #define NHU_RUNNING    2
        !           174: #define NHU_DIRTY      3
        !           175: 
        !           176: typedef struct network {
        !           177:   struct rte *routes;                  /* Available routes for this network */
        !           178:   struct fib_node n;                   /* FIB flags reserved for kernel syncer */
        !           179: } net;
        !           180: 
        !           181: struct hostcache {
        !           182:   slab *slab;                          /* Slab holding all hostentries */
        !           183:   struct hostentry **hash_table;       /* Hash table for hostentries */
        !           184:   unsigned hash_order, hash_shift;
        !           185:   unsigned hash_max, hash_min;
        !           186:   unsigned hash_items;
        !           187:   linpool *lp;                         /* Linpool for trie */
        !           188:   struct f_trie *trie;                 /* Trie of prefixes that might affect hostentries */
        !           189:   list hostentries;                    /* List of all hostentries */
        !           190:   byte update_hostcache;
        !           191: };
        !           192: 
        !           193: struct hostentry {
        !           194:   node ln;
        !           195:   ip_addr addr;                                /* IP address of host, part of key */
        !           196:   ip_addr link;                                /* (link-local) IP address of host, used as gw
        !           197:                                           if host is directly attached */
        !           198:   struct rtable *tab;                  /* Dependent table, part of key */
        !           199:   struct hostentry *next;              /* Next in hash chain */
        !           200:   unsigned hash_key;                   /* Hash key */
        !           201:   unsigned uc;                         /* Use count */
        !           202:   struct rta *src;                     /* Source rta entry */
        !           203:   byte dest;                           /* Chosen route destination type (RTD_...) */
        !           204:   byte nexthop_linkable;               /* Nexthop list is completely non-device */
        !           205:   u32 igp_metric;                      /* Chosen route IGP metric */
        !           206: };
        !           207: 
        !           208: typedef struct rte {
        !           209:   struct rte *next;
        !           210:   net *net;                            /* Network this RTE belongs to */
        !           211:   struct channel *sender;              /* Channel used to send the route to the routing table */
        !           212:   struct rta *attrs;                   /* Attributes of this route */
        !           213:   byte flags;                          /* Flags (REF_...) */
        !           214:   byte pflags;                         /* Protocol-specific flags */
        !           215:   word pref;                           /* Route preference */
        !           216:   btime lastmod;                       /* Last modified */
        !           217:   union {                              /* Protocol-dependent data (metrics etc.) */
        !           218: #ifdef CONFIG_RIP
        !           219:     struct {
        !           220:       struct iface *from;              /* Incoming iface */
        !           221:       u8 metric;                       /* RIP metric */
        !           222:       u16 tag;                         /* External route tag */
        !           223:     } rip;
        !           224: #endif
        !           225: #ifdef CONFIG_OSPF
        !           226:     struct {
        !           227:       u32 metric1, metric2;            /* OSPF Type 1 and Type 2 metrics */
        !           228:       u32 tag;                         /* External route tag */
        !           229:       u32 router_id;                   /* Router that originated this route */
        !           230:     } ospf;
        !           231: #endif
        !           232: #ifdef CONFIG_BGP
        !           233:     struct {
        !           234:       u8 suppressed;                   /* Used for deterministic MED comparison */
        !           235:       s8 stale;                                /* Route is LLGR_STALE, -1 if unknown */
        !           236:     } bgp;
        !           237: #endif
        !           238: #ifdef CONFIG_BABEL
        !           239:     struct {
        !           240:       u16 seqno;                       /* Babel seqno */
        !           241:       u16 metric;                      /* Babel metric */
        !           242:       u64 router_id;                   /* Babel router id */
        !           243:     } babel;
        !           244: #endif
        !           245:     struct {                           /* Routes generated by krt sync (both temporary and inherited ones) */
        !           246:       s8 src;                          /* Alleged route source (see krt.h) */
        !           247:       u8 proto;                                /* Kernel source protocol ID */
        !           248:       u8 seen;                         /* Seen during last scan */
        !           249:       u8 best;                         /* Best route in network, propagated to core */
        !           250:       u32 metric;                      /* Kernel metric */
        !           251:     } krt;
        !           252:   } u;
        !           253: } rte;
        !           254: 
        !           255: #define REF_COW                1               /* Copy this rte on write */
        !           256: #define REF_FILTERED   2               /* Route is rejected by import filter */
        !           257: #define REF_STALE      4               /* Route is stale in a refresh cycle */
        !           258: #define REF_DISCARD    8               /* Route is scheduled for discard */
        !           259: #define REF_MODIFY     16              /* Route is scheduled for modify */
        !           260: 
        !           261: /* Route is valid for propagation (may depend on other flags in the future), accepts NULL */
        !           262: static inline int rte_is_valid(rte *r) { return r && !(r->flags & REF_FILTERED); }
        !           263: 
        !           264: /* Route just has REF_FILTERED flag */
        !           265: static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED); }
        !           266: 
        !           267: 
        !           268: /* Types of route announcement, also used as flags */
        !           269: #define RA_UNDEF       0               /* Undefined RA type */
        !           270: #define RA_OPTIMAL     1               /* Announcement of optimal route change */
        !           271: #define RA_ACCEPTED    2               /* Announcement of first accepted route */
        !           272: #define RA_ANY         3               /* Announcement of any route change */
        !           273: #define RA_MERGED      4               /* Announcement of optimal route merged with next ones */
        !           274: 
        !           275: /* Return value of preexport() callback */
        !           276: #define RIC_ACCEPT     1               /* Accepted by protocol */
        !           277: #define RIC_PROCESS    0               /* Process it through import filter */
        !           278: #define RIC_REJECT     -1              /* Rejected by protocol */
        !           279: #define RIC_DROP       -2              /* Silently dropped by protocol */
        !           280: 
        !           281: extern list routing_tables;
        !           282: struct config;
        !           283: 
        !           284: void rt_init(void);
        !           285: void rt_preconfig(struct config *);
        !           286: void rt_commit(struct config *new, struct config *old);
        !           287: void rt_lock_table(rtable *);
        !           288: void rt_unlock_table(rtable *);
        !           289: void rt_setup(pool *, rtable *, struct rtable_config *);
        !           290: static inline net *net_find(rtable *tab, const net_addr *addr) { return (net *) fib_find(&tab->fib, addr); }
        !           291: static inline net *net_find_valid(rtable *tab, const net_addr *addr)
        !           292: { net *n = net_find(tab, addr); return (n && rte_is_valid(n->routes)) ? n : NULL; }
        !           293: static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) fib_get(&tab->fib, addr); }
        !           294: void *net_route(rtable *tab, const net_addr *n);
        !           295: int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
        !           296: rte *rte_find(net *net, struct rte_src *src);
        !           297: rte *rte_get_temp(struct rta *);
        !           298: void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
        !           299: /* rte_update() moved to protocol.h to avoid dependency conflicts */
        !           300: int rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter);
        !           301: rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int silent);
        !           302: void rt_refresh_begin(rtable *t, struct channel *c);
        !           303: void rt_refresh_end(rtable *t, struct channel *c);
        !           304: void rt_modify_stale(rtable *t, struct channel *c);
        !           305: void rt_schedule_prune(rtable *t);
        !           306: void rte_dump(rte *);
        !           307: void rte_free(rte *);
        !           308: rte *rte_do_cow(rte *);
        !           309: static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
        !           310: rte *rte_cow_rta(rte *r, linpool *lp);
        !           311: void rte_init_tmp_attrs(struct rte *r, linpool *lp, uint max);
        !           312: void rte_make_tmp_attr(struct rte *r, uint id, uint type, uintptr_t val);
        !           313: void rte_make_tmp_attrs(struct rte **r, struct linpool *pool, struct rta **old_attrs);
        !           314: uintptr_t rte_store_tmp_attr(struct rte *r, uint id);
        !           315: void rt_dump(rtable *);
        !           316: void rt_dump_all(void);
        !           317: int rt_feed_channel(struct channel *c);
        !           318: void rt_feed_channel_abort(struct channel *c);
        !           319: int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
        !           320: int rt_reload_channel(struct channel *c);
        !           321: void rt_reload_channel_abort(struct channel *c);
        !           322: void rt_prune_sync(rtable *t, int all);
        !           323: int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, int refeed);
        !           324: struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
        !           325: 
        !           326: 
        !           327: /* Default limit for ECMP next hops, defined in sysdep code */
        !           328: extern const int rt_default_ecmp;
        !           329: 
        !           330: struct rt_show_data_rtable {
        !           331:   node n;
        !           332:   rtable *table;
        !           333:   struct channel *export_channel;
        !           334: };
        !           335: 
        !           336: struct rt_show_data {
        !           337:   net_addr *addr;
        !           338:   list tables;
        !           339:   struct rt_show_data_rtable *tab;     /* Iterator over table list */
        !           340:   struct rt_show_data_rtable *last_table; /* Last table in output */
        !           341:   struct fib_iterator fit;             /* Iterator over networks in table */
        !           342:   int verbose, tables_defined_by;
        !           343:   const struct filter *filter;
        !           344:   struct proto *show_protocol;
        !           345:   struct proto *export_protocol;
        !           346:   struct channel *export_channel;
        !           347:   struct config *running_on_config;
        !           348:   int export_mode, primary_only, filtered, stats, show_for;
        !           349: 
        !           350:   int table_open;                      /* Iteration (fit) is open */
        !           351:   int net_counter, rt_counter, show_counter, table_counter;
        !           352:   int net_counter_last, rt_counter_last, show_counter_last;
        !           353: };
        !           354: 
        !           355: void rt_show(struct rt_show_data *);
        !           356: struct rt_show_data_rtable * rt_show_add_table(struct rt_show_data *d, rtable *t);
        !           357: 
        !           358: /* Value of table definition mode in struct rt_show_data */
        !           359: #define RSD_TDB_DEFAULT          0             /* no table specified */
        !           360: #define RSD_TDB_INDIRECT  0            /* show route ... protocol P ... */
        !           361: #define RSD_TDB_ALL      RSD_TDB_SET                   /* show route ... table all ... */
        !           362: #define RSD_TDB_DIRECT   RSD_TDB_SET | RSD_TDB_NMN     /* show route ... table X table Y ... */
        !           363: 
        !           364: #define RSD_TDB_SET      0x1           /* internal: show empty tables */
        !           365: #define RSD_TDB_NMN      0x2           /* internal: need matching net */
        !           366: 
        !           367: /* Value of export_mode in struct rt_show_data */
        !           368: #define RSEM_NONE      0               /* Export mode not used */
        !           369: #define RSEM_PREEXPORT 1               /* Routes ready for export, before filtering */
        !           370: #define RSEM_EXPORT    2               /* Routes accepted by export filter */
        !           371: #define RSEM_NOEXPORT  3               /* Routes rejected by export filter */
        !           372: 
        !           373: /*
        !           374:  *     Route Attributes
        !           375:  *
        !           376:  *     Beware: All standard BGP attributes must be represented here instead
        !           377:  *     of making them local to the route. This is needed to ensure proper
        !           378:  *     construction of BGP route attribute lists.
        !           379:  */
        !           380: 
        !           381: /* Nexthop structure */
        !           382: struct nexthop {
        !           383:   ip_addr gw;                          /* Next hop */
        !           384:   struct iface *iface;                 /* Outgoing interface */
        !           385:   struct nexthop *next;
        !           386:   byte flags;
        !           387:   byte weight;
        !           388:   byte labels_orig;                    /* Number of labels before hostentry was applied */
        !           389:   byte labels;                         /* Number of all labels */
        !           390:   u32 label[0];
        !           391: };
        !           392: 
        !           393: #define RNF_ONLINK             0x1     /* Gateway is onlink regardless of IP ranges */
        !           394: 
        !           395: 
        !           396: struct rte_src {
        !           397:   struct rte_src *next;                        /* Hash chain */
        !           398:   struct proto *proto;                 /* Protocol the source is based on */
        !           399:   u32 private_id;                      /* Private ID, assigned by the protocol */
        !           400:   u32 global_id;                       /* Globally unique ID of the source */
        !           401:   unsigned uc;                         /* Use count */
        !           402: };
        !           403: 
        !           404: 
        !           405: typedef struct rta {
        !           406:   struct rta *next, **pprev;           /* Hash chain */
        !           407:   u32 uc;                              /* Use count */
        !           408:   u32 hash_key;                                /* Hash over important fields */
        !           409:   struct ea_list *eattrs;              /* Extended Attribute chain */
        !           410:   struct rte_src *src;                 /* Route source that created the route */
        !           411:   struct hostentry *hostentry;         /* Hostentry for recursive next-hops */
        !           412:   ip_addr from;                                /* Advertising router */
        !           413:   u32 igp_metric;                      /* IGP metric to next hop (for iBGP routes) */
        !           414:   u8 source;                           /* Route source (RTS_...) */
        !           415:   u8 scope;                            /* Route scope (SCOPE_... -- see ip.h) */
        !           416:   u8 dest;                             /* Route destination type (RTD_...) */
        !           417:   u8 aflags;
        !           418:   struct nexthop nh;                   /* Next hop */
        !           419: } rta;
        !           420: 
        !           421: #define RTS_DUMMY 0                    /* Dummy route to be removed soon */
        !           422: #define RTS_STATIC 1                   /* Normal static route */
        !           423: #define RTS_INHERIT 2                  /* Route inherited from kernel */
        !           424: #define RTS_DEVICE 3                   /* Device route */
        !           425: #define RTS_STATIC_DEVICE 4            /* Static device route */
        !           426: #define RTS_REDIRECT 5                 /* Learned via redirect */
        !           427: #define RTS_RIP 6                      /* RIP route */
        !           428: #define RTS_OSPF 7                     /* OSPF route */
        !           429: #define RTS_OSPF_IA 8                  /* OSPF inter-area route */
        !           430: #define RTS_OSPF_EXT1 9                        /* OSPF external route type 1 */
        !           431: #define RTS_OSPF_EXT2 10               /* OSPF external route type 2 */
        !           432: #define RTS_BGP 11                     /* BGP route */
        !           433: #define RTS_PIPE 12                    /* Inter-table wormhole */
        !           434: #define RTS_BABEL 13                   /* Babel route */
        !           435: #define RTS_RPKI 14                    /* Route Origin Authorization */
        !           436: #define RTS_PERF 15                    /* Perf checker */
        !           437: #define RTS_MAX 16
        !           438: 
        !           439: #define RTC_UNICAST 0
        !           440: #define RTC_BROADCAST 1
        !           441: #define RTC_MULTICAST 2
        !           442: #define RTC_ANYCAST 3                  /* IPv6 Anycast */
        !           443: 
        !           444: #define RTD_NONE 0                     /* Undefined next hop */
        !           445: #define RTD_UNICAST 1                  /* Next hop is neighbor router */
        !           446: #define RTD_BLACKHOLE 2                        /* Silently drop packets */
        !           447: #define RTD_UNREACHABLE 3              /* Reject as unreachable */
        !           448: #define RTD_PROHIBIT 4                 /* Administratively prohibited */
        !           449: #define RTD_MAX 5
        !           450: 
        !           451:                                        /* Flags for net->n.flags, used by kernel syncer */
        !           452: #define KRF_INSTALLED 0x80             /* This route should be installed in the kernel */
        !           453: #define KRF_SYNC_ERROR 0x40            /* Error during kernel table synchronization */
        !           454: 
        !           455: #define RTAF_CACHED 1                  /* This is a cached rta */
        !           456: 
        !           457: #define IGP_METRIC_UNKNOWN 0x80000000  /* Default igp_metric used when no other
        !           458:                                           protocol-specific metric is availabe */
        !           459: 
        !           460: 
        !           461: const char * rta_dest_names[RTD_MAX];
        !           462: 
        !           463: static inline const char *rta_dest_name(uint n)
        !           464: { return (n < RTD_MAX) ? rta_dest_names[n] : "???"; }
        !           465: 
        !           466: /* Route has regular, reachable nexthop (i.e. not RTD_UNREACHABLE and like) */
        !           467: static inline int rte_is_reachable(rte *r)
        !           468: { return r->attrs->dest == RTD_UNICAST; }
        !           469: 
        !           470: 
        !           471: /*
        !           472:  *     Extended Route Attributes
        !           473:  */
        !           474: 
        !           475: typedef struct eattr {
        !           476:   word id;                             /* EA_CODE(PROTOCOL_..., protocol-dependent ID) */
        !           477:   byte flags;                          /* Protocol-dependent flags */
        !           478:   byte type;                           /* Attribute type and several flags (EAF_...) */
        !           479:   union {
        !           480:     u32 data;
        !           481:     const struct adata *ptr;                   /* Attribute data elsewhere */
        !           482:   } u;
        !           483: } eattr;
        !           484: 
        !           485: 
        !           486: #define EA_CODE(proto,id) (((proto) << 8) | (id))
        !           487: #define EA_ID(ea) ((ea) & 0xff)
        !           488: #define EA_PROTO(ea) ((ea) >> 8)
        !           489: #define EA_ID_FLAG(ea) (1 << EA_ID(ea))
        !           490: #define EA_CUSTOM(id) ((id) | EA_CUSTOM_BIT)
        !           491: #define EA_IS_CUSTOM(ea) ((ea) & EA_CUSTOM_BIT)
        !           492: #define EA_CUSTOM_ID(ea) ((ea) & ~EA_CUSTOM_BIT)
        !           493: 
        !           494: const char *ea_custom_name(uint ea);
        !           495: 
        !           496: #define EA_GEN_IGP_METRIC EA_CODE(PROTOCOL_NONE, 0)
        !           497: 
        !           498: #define EA_CODE_MASK 0xffff
        !           499: #define EA_CUSTOM_BIT 0x8000
        !           500: #define EA_ALLOW_UNDEF 0x10000         /* ea_find: allow EAF_TYPE_UNDEF */
        !           501: #define EA_BIT(n) ((n) << 24)          /* Used in bitfield accessors */
        !           502: #define EA_BIT_GET(ea) ((ea) >> 24)
        !           503: 
        !           504: #define EAF_TYPE_MASK 0x1f             /* Mask with this to get type */
        !           505: #define EAF_TYPE_INT 0x01              /* 32-bit unsigned integer number */
        !           506: #define EAF_TYPE_OPAQUE 0x02           /* Opaque byte string (not filterable) */
        !           507: #define EAF_TYPE_IP_ADDRESS 0x04       /* IP address */
        !           508: #define EAF_TYPE_ROUTER_ID 0x05                /* Router ID (IPv4 address) */
        !           509: #define EAF_TYPE_AS_PATH 0x06          /* BGP AS path (encoding per RFC 1771:4.3) */
        !           510: #define EAF_TYPE_BITFIELD 0x09         /* 32-bit embedded bitfield */
        !           511: #define EAF_TYPE_INT_SET 0x0a          /* Set of u32's (e.g., a community list) */
        !           512: #define EAF_TYPE_EC_SET 0x0e           /* Set of pairs of u32's - ext. community list */
        !           513: #define EAF_TYPE_LC_SET 0x12           /* Set of triplets of u32's - large community list */
        !           514: #define EAF_TYPE_UNDEF 0x1f            /* `force undefined' entry */
        !           515: #define EAF_EMBEDDED 0x01              /* Data stored in eattr.u.data (part of type spec) */
        !           516: #define EAF_VAR_LENGTH 0x02            /* Attribute length is variable (part of type spec) */
        !           517: #define EAF_ORIGINATED 0x20            /* The attribute has originated locally */
        !           518: #define EAF_FRESH 0x40                 /* An uncached attribute (e.g. modified in export filter) */
        !           519: 
        !           520: typedef struct adata {
        !           521:   uint length;                         /* Length of data */
        !           522:   byte data[0];
        !           523: } adata;
        !           524: 
        !           525: extern const adata null_adata;         /* adata of length 0 */
        !           526: 
        !           527: static inline struct adata *
        !           528: lp_alloc_adata(struct linpool *pool, uint len)
        !           529: {
        !           530:   struct adata *ad = lp_alloc(pool, sizeof(struct adata) + len);
        !           531:   ad->length = len;
        !           532:   return ad;
        !           533: }
        !           534: 
        !           535: static inline int adata_same(const struct adata *a, const struct adata *b)
        !           536: { return (a->length == b->length && !memcmp(a->data, b->data, a->length)); }
        !           537: 
        !           538: 
        !           539: typedef struct ea_list {
        !           540:   struct ea_list *next;                        /* In case we have an override list */
        !           541:   byte flags;                          /* Flags: EALF_... */
        !           542:   byte rfu;
        !           543:   word count;                          /* Number of attributes */
        !           544:   eattr attrs[0];                      /* Attribute definitions themselves */
        !           545: } ea_list;
        !           546: 
        !           547: #define EALF_SORTED 1                  /* Attributes are sorted by code */
        !           548: #define EALF_BISECT 2                  /* Use interval bisection for searching */
        !           549: #define EALF_CACHED 4                  /* Attributes belonging to cached rta */
        !           550: #define EALF_TEMP 8                    /* Temporary ea_list added by make_tmp_attrs hooks */
        !           551: 
        !           552: struct rte_src *rt_find_source(struct proto *p, u32 id);
        !           553: struct rte_src *rt_get_source(struct proto *p, u32 id);
        !           554: static inline void rt_lock_source(struct rte_src *src) { src->uc++; }
        !           555: static inline void rt_unlock_source(struct rte_src *src) { src->uc--; }
        !           556: void rt_prune_sources(void);
        !           557: 
        !           558: struct ea_walk_state {
        !           559:   ea_list *eattrs;                     /* Ccurrent ea_list, initially set by caller */
        !           560:   eattr *ea;                           /* Current eattr, initially NULL */
        !           561:   u32 visited[4];                      /* Bitfield, limiting max to 128 */
        !           562: };
        !           563: 
        !           564: eattr *ea_find(ea_list *, unsigned ea);
        !           565: eattr *ea_walk(struct ea_walk_state *s, uint id, uint max);
        !           566: int ea_get_int(ea_list *, unsigned ea, int def);
        !           567: void ea_dump(ea_list *);
        !           568: void ea_sort(ea_list *);               /* Sort entries in all sub-lists */
        !           569: unsigned ea_scan(ea_list *);           /* How many bytes do we need for merged ea_list */
        !           570: void ea_merge(ea_list *from, ea_list *to); /* Merge sub-lists to allocated buffer */
        !           571: int ea_same(ea_list *x, ea_list *y);   /* Test whether two ea_lists are identical */
        !           572: uint ea_hash(ea_list *e);      /* Calculate 16-bit hash value */
        !           573: ea_list *ea_append(ea_list *to, ea_list *what);
        !           574: void ea_format_bitfield(struct eattr *a, byte *buf, int bufsize, const char **names, int min, int max);
        !           575: 
        !           576: #define ea_normalize(ea) do { \
        !           577:   if (ea->next) { \
        !           578:     ea_list *t = alloca(ea_scan(ea)); \
        !           579:     ea_merge(ea, t); \
        !           580:     ea = t; \
        !           581:   } \
        !           582:   ea_sort(ea); \
        !           583:   if (ea->count == 0) \
        !           584:     ea = NULL; \
        !           585: } while(0) \
        !           586: 
        !           587: static inline eattr *
        !           588: ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, uintptr_t val)
        !           589: {
        !           590:   ea_list *a = lp_alloc(pool, sizeof(ea_list) + sizeof(eattr));
        !           591:   eattr *e = &a->attrs[0];
        !           592: 
        !           593:   a->flags = EALF_SORTED;
        !           594:   a->count = 1;
        !           595:   a->next = *to;
        !           596:   *to = a;
        !           597: 
        !           598:   e->id = id;
        !           599:   e->type = type;
        !           600:   e->flags = flags;
        !           601: 
        !           602:   if (type & EAF_EMBEDDED)
        !           603:     e->u.data = (u32) val;
        !           604:   else
        !           605:     e->u.ptr = (struct adata *) val;
        !           606: 
        !           607:   return e;
        !           608: }
        !           609: 
        !           610: static inline void
        !           611: ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 val)
        !           612: { ea_set_attr(to, pool, id, flags, type, (uintptr_t) val); }
        !           613: 
        !           614: static inline void
        !           615: ea_set_attr_ptr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, struct adata *val)
        !           616: { ea_set_attr(to, pool, id, flags, type, (uintptr_t) val); }
        !           617: 
        !           618: static inline void
        !           619: ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, void *data, uint len)
        !           620: {
        !           621:   struct adata *a = lp_alloc_adata(pool, len);
        !           622:   memcpy(a->data, data, len);
        !           623:   ea_set_attr(to, pool, id, flags, type, (uintptr_t) a);
        !           624: }
        !           625: 
        !           626: 
        !           627: #define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
        !           628: 
        !           629: static inline size_t nexthop_size(const struct nexthop *nh)
        !           630: { return sizeof(struct nexthop) + sizeof(u32)*nh->labels; }
        !           631: int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops */
        !           632: static inline int nexthop_same(struct nexthop *x, struct nexthop *y)
        !           633: { return (x == y) || nexthop__same(x, y); }
        !           634: struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp);
        !           635: struct nexthop *nexthop_sort(struct nexthop *x);
        !           636: static inline void nexthop_link(struct rta *a, struct nexthop *from)
        !           637: { memcpy(&a->nh, from, nexthop_size(from)); }
        !           638: void nexthop_insert(struct nexthop **n, struct nexthop *y);
        !           639: int nexthop_is_sorted(struct nexthop *x);
        !           640: 
        !           641: void rta_init(void);
        !           642: static inline size_t rta_size(const rta *a) { return sizeof(rta) + sizeof(u32)*a->nh.labels; }
        !           643: #define RTA_MAX_SIZE (sizeof(rta) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
        !           644: rta *rta_lookup(rta *);                        /* Get rta equivalent to this one, uc++ */
        !           645: static inline int rta_is_cached(rta *r) { return r->aflags & RTAF_CACHED; }
        !           646: static inline rta *rta_clone(rta *r) { r->uc++; return r; }
        !           647: void rta__free(rta *r);
        !           648: static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); }
        !           649: rta *rta_do_cow(rta *o, linpool *lp);
        !           650: static inline rta * rta_cow(rta *r, linpool *lp) { return rta_is_cached(r) ? rta_do_cow(r, lp) : r; }
        !           651: void rta_dump(rta *);
        !           652: void rta_dump_all(void);
        !           653: void rta_show(struct cli *, rta *);
        !           654: 
        !           655: u32 rt_get_igp_metric(rte *rt);
        !           656: struct hostentry * rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep);
        !           657: void rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls);
        !           658: 
        !           659: static inline void
        !           660: rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr gw, ip_addr ll, mpls_label_stack *mls)
        !           661: {
        !           662:   rta_apply_hostentry(a, rt_get_hostentry(tab, gw, ll, dep), mls);
        !           663: }
        !           664: 
        !           665: /*
        !           666:  * rta_set_recursive_next_hop() acquires hostentry from hostcache and fills
        !           667:  * rta->hostentry field.  New hostentry has zero use count. Cached rta locks its
        !           668:  * hostentry (increases its use count), uncached rta does not lock it. Hostentry
        !           669:  * with zero use count is removed asynchronously during host cache update,
        !           670:  * therefore it is safe to hold such hostentry temorarily. Hostentry holds a
        !           671:  * lock for a 'source' rta, mainly to share multipath nexthops.
        !           672:  *
        !           673:  * There is no need to hold a lock for hostentry->dep table, because that table
        !           674:  * contains routes responsible for that hostentry, and therefore is non-empty if
        !           675:  * given hostentry has non-zero use count. If the hostentry has zero use count,
        !           676:  * the entry is removed before dep is referenced.
        !           677:  *
        !           678:  * The protocol responsible for routes with recursive next hops should hold a
        !           679:  * lock for a 'source' table governing that routes (argument tab to
        !           680:  * rta_set_recursive_next_hop()), because its routes reference hostentries
        !           681:  * (through rta) related to the governing table. When all such routes are
        !           682:  * removed, rtas are immediately removed achieving zero uc. Then the 'source'
        !           683:  * table lock could be immediately released, although hostentries may still
        !           684:  * exist - they will be freed together with the 'source' table.
        !           685:  */
        !           686: 
        !           687: static inline void rt_lock_hostentry(struct hostentry *he) { if (he) he->uc++; }
        !           688: static inline void rt_unlock_hostentry(struct hostentry *he) { if (he) he->uc--; }
        !           689: 
        !           690: /*
        !           691:  *     Default protocol preferences
        !           692:  */
        !           693: 
        !           694: #define DEF_PREF_DIRECT                240     /* Directly connected */
        !           695: #define DEF_PREF_STATIC                200     /* Static route */
        !           696: #define DEF_PREF_OSPF          150     /* OSPF intra-area, inter-area and type 1 external routes */
        !           697: #define DEF_PREF_BABEL         130     /* Babel */
        !           698: #define DEF_PREF_RIP           120     /* RIP */
        !           699: #define DEF_PREF_BGP           100     /* BGP */
        !           700: #define DEF_PREF_RPKI          100     /* RPKI */
        !           701: #define DEF_PREF_INHERITED     10      /* Routes inherited from other routing daemons */
        !           702: 
        !           703: /*
        !           704:  *     Route Origin Authorization
        !           705:  */
        !           706: 
        !           707: #define ROA_UNKNOWN    0
        !           708: #define ROA_VALID      1
        !           709: #define ROA_INVALID    2
        !           710: 
        !           711: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>