File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / nest / route.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Aug 22 12:33:54 2017 UTC (6 years, 10 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_3p0, v1_6_3, HEAD
bird 1.6.3

    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>