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

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