summaryrefslogtreecommitdiff
path: root/lib/route.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/route.h')
-rw-r--r--lib/route.h65
1 files changed, 48 insertions, 17 deletions
diff --git a/lib/route.h b/lib/route.h
index df648cf9..1ade1a81 100644
--- a/lib/route.h
+++ b/lib/route.h
@@ -69,13 +69,18 @@ void rt_prune_sources(void);
struct nexthop {
ip_addr gw; /* Next hop */
struct iface *iface; /* Outgoing interface */
- struct nexthop *next;
byte flags;
byte weight;
byte labels; /* Number of all labels */
u32 label[0];
};
+/* For packing one into eattrs */
+struct nexthop_adata {
+ struct adata ad;
+ struct nexthop nh;
+};
+
#define RNF_ONLINK 0x1 /* Gateway is onlink regardless of IP ranges */
@@ -87,7 +92,6 @@ typedef struct rta {
struct hostentry *hostentry; /* Hostentry for recursive next-hops */
u16 cached:1; /* Are attributes cached? */
u16 dest:4; /* Route destination type (RTD_...) */
- struct nexthop nh; /* Next hop */
} rta;
#define RTS_STATIC 1 /* Normal static route */
@@ -288,9 +292,22 @@ ea_set_attr_u32(ea_list **to, const struct ea_class *def, uint flags, u64 data)
{ ea_set_attr(to, EA_LITERAL_EMBEDDED(def, flags, data)); }
static inline void
-ea_set_attr_data(ea_list **to, const struct ea_class *def, uint flags, void *data, uint len)
+ea_set_attr_data(ea_list **to, const struct ea_class *def, uint flags, const void *data, uint len)
{ ea_set_attr(to, EA_LITERAL_STORE_ADATA(def, flags, data, len)); }
+static inline void
+ea_copy_attr(ea_list **to, ea_list *from, const struct ea_class *def)
+{
+ eattr *e = ea_find_by_class(from, def);
+ if (e)
+ if (e->type & EAF_EMBEDDED)
+ ea_set_attr_u32(to, def, e->flags, e->u.data);
+ else
+ ea_set_attr_data(to, def, e->flags, e->u.ptr->data, e->u.ptr->length);
+ else
+ ea_unset_attr(to, 0, def);
+}
+
/*
* Common route attributes
*/
@@ -319,25 +336,39 @@ static inline u32 rt_get_source_attr(const rte *rt)
* to add additional labels to the resolved nexthop */
extern struct ea_class ea_mpls_labels;
+/* Next hop: For now, stored as adata */
+extern struct ea_class ea_gen_nexthop;
+
/* Next hop structures */
-#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
+#define NEXTHOP_ALIGNMENT (_Alignof(struct nexthop))
+#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
+#define NEXTHOP_SIZE(_nh) NEXTHOP_SIZE_CNT(((_nh)->labels))
+#define NEXTHOP_SIZE_CNT(cnt) BIRD_ALIGN((sizeof(struct nexthop) + sizeof(u32) * (cnt)), NEXTHOP_ALIGNMENT)
+#define nexthop_size(nh) NEXTHOP_SIZE((nh))
+
+#define NEXTHOP_NEXT(_nh) ((void *) (_nh) + NEXTHOP_SIZE(_nh))
+#define NEXTHOP_END(_nhad) ((_nhad)->ad.data + (_nhad)->ad.length)
+#define NEXTHOP_VALID(_nh, _nhad) ((void *) (_nh) < (void *) NEXTHOP_END(_nhad))
+#define NEXTHOP_ONE(_nhad) (NEXTHOP_NEXT(&(_nhad)->nh) == NEXTHOP_END(_nhad))
+
+#define NEXTHOP_WALK(_iter, _nhad) for ( \
+ struct nexthop *_iter = &(_nhad)->nh; \
+ (void *) _iter < (void *) NEXTHOP_END(_nhad); \
+ _iter = NEXTHOP_NEXT(_iter))
+
+
+static inline int nexthop_same(struct nexthop_adata *x, struct nexthop_adata *y)
+{ return adata_same(&x->ad, &y->ad); }
+struct nexthop_adata *nexthop_merge(struct nexthop_adata *x, struct nexthop_adata *y, int max, linpool *lp);
+struct nexthop_adata *nexthop_sort(struct nexthop_adata *x, linpool *lp);
+int nexthop_is_sorted(struct nexthop_adata *x);
+
-static inline size_t nexthop_size(const struct nexthop *nh)
-{ return sizeof(struct nexthop) + sizeof(u32)*nh->labels; }
-int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops */
-static inline int nexthop_same(struct nexthop *x, struct nexthop *y)
-{ return (x == y) || nexthop__same(x, y); }
-struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp);
-struct nexthop *nexthop_sort(struct nexthop *x);
-static inline void nexthop_link(struct rta *a, struct nexthop *from)
-{ memcpy(&a->nh, from, nexthop_size(from)); }
-void nexthop_insert(struct nexthop **n, struct nexthop *y);
-int nexthop_is_sorted(struct nexthop *x);
void rta_init(void);
-static inline size_t rta_size(const rta *a) { return sizeof(rta) + sizeof(u32)*a->nh.labels; }
-#define RTA_MAX_SIZE (sizeof(rta) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
+#define rta_size(...) (sizeof(rta))
+#define RTA_MAX_SIZE (sizeof(rta))
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
static inline int rta_is_cached(rta *r) { return r->cached; }
static inline rta *rta_clone(rta *r) { r->uc++; return r; }