diff options
author | Maria Matejka <mq@ucw.cz> | 2022-05-15 18:09:30 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-05-30 14:39:09 +0200 |
commit | 950775f6fa3d569a9d7cd05e33538d35e895d688 (patch) | |
tree | 81b4b23d5695e209301b252d0d282b05a0d67ac1 /lib/route.h | |
parent | 4fe9881d625f10e44109a649e369a413bd98de71 (diff) |
Route destination field merged with nexthop attribute; splitting flowspec validation result out.
As there is either a nexthop or another destination specification
(or othing in case of ROAs and Flowspec), it may be merged together.
This code is somehow quirky and should be replaced in future by better
implementation of nexthop.
Also flowspec validation result has its own attribute now as it doesn't
have anything to do with route nexthop.
Diffstat (limited to 'lib/route.h')
-rw-r--r-- | lib/route.h | 60 |
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)) |