#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/timer.h"
+#include "nest/protocol.h"
struct protocol;
struct proto;
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
int gc_max_ops; /* Maximum number of operations before GC is run */
int gc_min_time; /* Minimum time between two consecutive GC runs */
+ byte sorted; /* Routes of network are sorted according to rte_better() */
};
typedef struct rtable {
int gc_counter; /* Number of operations since last GC */
bird_clock_t gc_time; /* Time of last GC */
byte gc_scheduled; /* GC is scheduled */
+ byte prune_state; /* Table prune state, 1 -> prune is running */
byte hcu_scheduled; /* Hostcache update is scheduled */
byte nhu_state; /* Next Hop Update state */
+ struct fib_iterator prune_fit; /* Rtable prune FIB iterator */
struct fib_iterator nhu_fit; /* Next Hop Update FIB iterator */
} rtable;
typedef struct rte {
struct rte *next;
net *net; /* Network this RTE belongs to */
- struct proto *sender; /* Protocol instance that sent the route to the routing table */
+ struct announce_hook *sender; /* Announce hook used to send the route to the routing table */
struct rta *attrs; /* Attributes of this route */
byte flags; /* Flags (REF_...) */
byte pflags; /* Protocol-specific flags */
u32 tag; /* External route tag */
u32 router_id; /* Router that originated this route */
} ospf;
+#endif
+#ifdef CONFIG_BGP
+ struct {
+ u8 suppressed; /* Used for deterministic MED comparison */
+ } bgp;
#endif
struct { /* Routes generated by krt sync (both temporary and inherited ones) */
s8 src; /* Alleged route source (see krt.h) */
} u;
} rte;
-#define REF_COW 1 /* Copy this rte on write */
+#define REF_COW 1 /* Copy this rte on write */
+#define REF_FILTERED 2 /* Route is rejected by import filter */
+
+/* Route is valid for propagation (may depend on other flags in the future), accepts NULL */
+static inline int rte_is_valid(rte *r) { return r && !(r->flags & REF_FILTERED); }
+
+/* Route just has REF_FILTERED flag */
+static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED); }
+
/* Types of route announcement, also used as flags */
-#define RA_OPTIMAL 1 /* Announcement of optimal route change */
-#define RA_ANY 2 /* Announcement of any route change */
+#define RA_OPTIMAL 1 /* Announcement of optimal route change */
+#define RA_ACCEPTED 2 /* Announcement of first accepted route */
+#define RA_ANY 3 /* Announcement of any route change */
+
+/* Return value of import_control() callback */
+#define RIC_ACCEPT 1 /* Accepted by protocol */
+#define RIC_PROCESS 0 /* Process it through import filter */
+#define RIC_REJECT -1 /* Rejected by protocol */
+#define RIC_DROP -2 /* Silently dropped by protocol */
struct config;
static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
rte *rte_find(net *net, struct proto *p);
rte *rte_get_temp(struct rta *);
-void rte_update(rtable *tab, net *net, struct proto *p, struct proto *src, rte *new);
+void rte_update2(struct announce_hook *ah, net *net, rte *new, struct proto *src);
+static inline void rte_update(rtable *tab, net *net, struct proto *p, struct proto *src, rte *new) { rte_update2(p->main_ahook, net, new, src); }
void rte_discard(rtable *tab, rte *old);
+int rt_examine(rtable *t, ip_addr prefix, int pxlen, struct proto *p, struct filter *filter);
void rte_dump(rte *);
void rte_free(rte *);
rte *rte_do_cow(rte *);
void rt_dump_all(void);
int rt_feed_baby(struct proto *p);
void rt_feed_baby_abort(struct proto *p);
-void rt_prune_all(void);
+void rt_schedule_prune_all(void);
+int rt_prune_loop(void);
struct rtable_config *rt_new_table(struct symbol *s);
struct rt_show_data {
struct fib_iterator fit;
struct proto *show_protocol;
struct proto *export_protocol;
- int export_mode, primary_only;
+ int export_mode, primary_only, filtered;
struct config *running_on_config;
int net_counter, rt_counter, show_counter;
int stats, show_for;
#define RTD_MULTIPATH 5 /* Multipath route (nexthops != NULL) */
#define RTD_NONE 6 /* Invalid RTD */
+ /* Flags for net->n.flags, used by kernel syncer */
+#define KRF_INSTALLED 0x80 /* This route should be installed in the kernel */
+#define KRF_SYNC_ERROR 0x40 /* Error during kernel table synchronization */
+
#define RTAF_CACHED 1 /* This is a cached rta */
#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
#define EAF_TYPE_ROUTER_ID 0x05 /* Router ID (IPv4 address) */
#define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */
#define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */
+#define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */
#define EAF_TYPE_UNDEF 0x0f /* `force undefined' entry */
#define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */
#define EAF_VAR_LENGTH 0x02 /* Attribute length is variable (part of type spec) */
void ea_merge(ea_list *from, ea_list *to); /* Merge sub-lists to allocated buffer */
int ea_same(ea_list *x, ea_list *y); /* Test whether two ea_lists are identical */
unsigned int ea_hash(ea_list *e); /* Calculate 16-bit hash value */
-void ea_format(eattr *e, byte *buf);
-#define EA_FORMAT_BUF_SIZE 256
ea_list *ea_append(ea_list *to, ea_list *what);
int mpnh__same(struct mpnh *x, struct mpnh *y); /* Compare multipath nexthops */
#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
+
+/*
+ * Route Origin Authorization
+ */
+
+struct roa_item {
+ u32 asn;
+ byte maxlen;
+ byte src;
+ struct roa_item *next;
+};
+
+struct roa_node {
+ struct fib_node n;
+ struct roa_item *items;
+ // u32 cached_asn;
+};
+
+struct roa_table {
+ node n; /* Node in roa_table_list */
+ struct fib fib;
+ char *name; /* Name of this ROA table */
+ struct roa_table_config *cf; /* Configuration of this ROA table */
+};
+
+struct roa_item_config {
+ ip_addr prefix;
+ byte pxlen, maxlen;
+ u32 asn;
+ struct roa_item_config *next;
+};
+
+struct roa_table_config {
+ node n; /* Node in config->rpa_tables */
+ char *name; /* Name of this ROA table */
+ struct roa_table *table;
+
+ struct roa_item_config *roa_items; /* Preconfigured ROA items */
+
+ // char *filename;
+ // int gc_max_ops; /* Maximum number of operations before GC is run */
+ // int gc_min_time; /* Minimum time between two consecutive GC runs */
+};
+
+struct roa_show_data {
+ struct fib_iterator fit;
+ struct roa_table *table;
+ ip_addr prefix;
+ byte pxlen;
+ byte mode; /* ROA_SHOW_* values */
+ u32 asn; /* Filter ASN, 0 -> all */
+};
+
+#define ROA_UNKNOWN 0
+#define ROA_VALID 1
+#define ROA_INVALID 2
+
+#define ROA_SRC_ANY 0
+#define ROA_SRC_CONFIG 1
+#define ROA_SRC_DYNAMIC 2
+
+#define ROA_SHOW_ALL 0
+#define ROA_SHOW_PX 1
+#define ROA_SHOW_IN 2
+#define ROA_SHOW_FOR 3
+
+extern struct roa_table *roa_table_default;
+
+void roa_add_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src);
+void roa_delete_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src);
+void roa_flush(struct roa_table *t, byte src);
+byte roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn);
+struct roa_table_config * roa_new_table_config(struct symbol *s);
+void roa_add_item_config(struct roa_table_config *rtc, ip_addr prefix, byte pxlen, byte maxlen, u32 asn);
+void roa_init(void);
+void roa_preconfig(struct config *c);
+void roa_commit(struct config *new, struct config *old);
+void roa_show(struct roa_show_data *d);
+
+
#endif