summaryrefslogtreecommitdiff
path: root/lib/route.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/route.h')
-rw-r--r--lib/route.h60
1 files changed, 53 insertions, 7 deletions
diff --git a/lib/route.h b/lib/route.h
index 3ce8021d..1d8877c8 100644
--- a/lib/route.h
+++ b/lib/route.h
@@ -76,9 +76,17 @@ struct nexthop {
/* For packing one into eattrs */
struct nexthop_adata {
struct adata ad;
- struct nexthop nh;
+ /* There is either a set of nexthops or a special destination (RTD_*) */
+ union {
+ struct nexthop nh;
+ uint dest;
+ };
};
+#define NEXTHOP_DEST_SIZE (OFFSETOF(struct nexthop_adata, dest) + sizeof(uint) - OFFSETOF(struct adata, data))
+#define NEXTHOP_DEST_LITERAL(x) ((struct nexthop_adata) { \
+ .ad.length = NEXTHOP_DEST_SIZE, .dest = (x), })
+
#define RNF_ONLINK 0x1 /* Gateway is onlink regardless of IP ranges */
@@ -88,7 +96,6 @@ typedef struct rta {
u32 hash_key; /* Hash over important fields */
struct ea_list *eattrs; /* Extended Attribute chain */
u16 cached:1; /* Are attributes cached? */
- u16 dest:4; /* Route destination type (RTD_...) */
} rta;
#define RTS_STATIC 1 /* Normal static route */
@@ -109,7 +116,7 @@ typedef struct rta {
#define RTS_MAX 16
#define RTD_NONE 0 /* Undefined next hop */
-#define RTD_UNICAST 1 /* Next hop is neighbor router */
+#define RTD_UNICAST 1 /* A standard next hop */
#define RTD_BLACKHOLE 2 /* Silently drop packets */
#define RTD_UNREACHABLE 3 /* Reject as unreachable */
#define RTD_PROHIBIT 4 /* Administratively prohibited */
@@ -120,10 +127,6 @@ extern const char * rta_dest_names[RTD_MAX];
static inline const char *rta_dest_name(uint n)
{ return (n < RTD_MAX) ? rta_dest_names[n] : "???"; }
-/* Route has regular, reachable nexthop (i.e. not RTD_UNREACHABLE and like) */
-static inline int rte_is_reachable(rte *r)
-{ return r->attrs->dest == RTD_UNICAST; }
-
/*
* Extended Route Attributes
@@ -331,9 +334,24 @@ extern struct ea_class ea_gen_source;
static inline u32 rt_get_source_attr(rte *rt)
{ return ea_get_int(rt->attrs->eattrs, &ea_gen_source, 0); }
+/* Flowspec validation result */
+#define FLOWSPEC_UNKNOWN 0
+#define FLOWSPEC_VALID 1
+#define FLOWSPEC_INVALID 2
+
+extern struct ea_class ea_gen_flowspec_valid;
+static inline u32 rt_get_flowspec_valid(rte *rt)
+{ return ea_get_int(rt->attrs->eattrs, &ea_gen_flowspec_valid, FLOWSPEC_UNKNOWN); }
+
/* Next hop: For now, stored as adata */
extern struct ea_class ea_gen_nexthop;
+static inline void ea_set_dest(struct ea_list **to, uint flags, uint dest)
+{
+ struct nexthop_adata nhad = NEXTHOP_DEST_LITERAL(dest);
+ ea_set_attr_data(to, &ea_gen_nexthop, flags, &nhad.ad.data, nhad.ad.length);
+}
+
/* Next hop structures */
#define NEXTHOP_ALIGNMENT (_Alignof(struct nexthop))
@@ -359,7 +377,35 @@ struct nexthop_adata *nexthop_merge(struct nexthop_adata *x, struct nexthop_adat
struct nexthop_adata *nexthop_sort(struct nexthop_adata *x, linpool *lp);
int nexthop_is_sorted(struct nexthop_adata *x);
+#define NEXTHOP_IS_REACHABLE(nhad) ((nhad)->ad.length > NEXTHOP_DEST_SIZE)
+/* Route has regular, reachable nexthop (i.e. not RTD_UNREACHABLE and like) */
+static inline int rte_is_reachable(rte *r)
+{
+ eattr *nhea = ea_find(r->attrs->eattrs, &ea_gen_nexthop);
+ if (!nhea)
+ return 0;
+
+ struct nexthop_adata *nhad = (void *) nhea->u.ptr;
+ return NEXTHOP_IS_REACHABLE(nhad);
+}
+
+static inline int nhea_dest(eattr *nhea)
+{
+ if (!nhea)
+ return RTD_NONE;
+
+ struct nexthop_adata *nhad = nhea ? (struct nexthop_adata *) nhea->u.ptr : NULL;
+ if (NEXTHOP_IS_REACHABLE(nhad))
+ return RTD_UNICAST;
+ else
+ return nhad->dest;
+}
+
+static inline int rte_dest(rte *r)
+{
+ return nhea_dest(ea_find(r->attrs->eattrs, &ea_gen_nexthop));
+}
void rta_init(void);
#define rta_size(...) (sizeof(rta))