File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / nest / route.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 19:50:23 2021 UTC (3 years, 3 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, HEAD
bird 1.6.8

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

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