summaryrefslogtreecommitdiff
path: root/nest/attrs.h
diff options
context:
space:
mode:
Diffstat (limited to 'nest/attrs.h')
-rw-r--r--nest/attrs.h110
1 files changed, 98 insertions, 12 deletions
diff --git a/nest/attrs.h b/nest/attrs.h
index 0171c6a8..810ff583 100644
--- a/nest/attrs.h
+++ b/nest/attrs.h
@@ -10,6 +10,9 @@
#define _BIRD_ATTRS_H_
#include <stdint.h>
+#include "lib/unaligned.h"
+#include "nest/route.h"
+
/* a-path.c */
@@ -27,32 +30,79 @@
struct f_tree;
-struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, u32 as);
-int as_path_convert_to_old(struct adata *path, byte *dst, int *new_used);
-int as_path_convert_to_new(struct adata *path, byte *dst, int req_as);
-void as_path_format(struct adata *path, byte *buf, uint size);
-int as_path_getlen(struct adata *path);
-int as_path_getlen_int(struct adata *path, int bs);
-int as_path_get_first(struct adata *path, u32 *orig_as);
-int as_path_get_last(struct adata *path, u32 *last_as);
-u32 as_path_get_last_nonaggregated(struct adata *path);
-int as_path_contains(struct adata *path, u32 as, int min);
-int as_path_match_set(struct adata *path, struct f_tree *set);
+int as_path_valid(byte *data, uint len, int bs, char *err, uint elen);
+int as_path_16to32(byte *dst, byte *src, uint len);
+int as_path_32to16(byte *dst, byte *src, uint len);
+int as_path_contains_as4(const struct adata *path);
+int as_path_contains_confed(const struct adata *path);
+struct adata *as_path_strip_confed(struct linpool *pool, const struct adata *op);
+struct adata *as_path_prepend2(struct linpool *pool, const struct adata *op, int seq, u32 as, int strip);
+struct adata *as_path_to_old(struct linpool *pool, const struct adata *path);
+void as_path_cut(struct adata *path, uint num);
+struct adata *as_path_merge(struct linpool *pool, struct adata *p1, struct adata *p2);
+void as_path_format(const struct adata *path, byte *buf, uint size);
+int as_path_getlen(const struct adata *path);
+int as_path_getlen_int(const struct adata *path, int bs);
+int as_path_get_first(const struct adata *path, u32 *orig_as);
+int as_path_get_last(const struct adata *path, u32 *last_as);
+u32 as_path_get_last_nonaggregated(const struct adata *path);
+int as_path_contains(const struct adata *path, u32 as, int min);
+int as_path_match_set(const struct adata *path, struct f_tree *set);
struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos);
+static inline struct adata *as_path_prepend(struct linpool *pool, const struct adata *path, u32 as)
+{ return as_path_prepend2(pool, path, AS_PATH_SEQUENCE, as, 0); }
+
#define PM_ASN 0
#define PM_QUESTION 1
#define PM_ASTERISK 2
#define PM_ASN_EXPR 3
+#define PM_ASN_RANGE 4
struct f_path_mask {
struct f_path_mask *next;
int kind;
uintptr_t val;
+ uintptr_t val2;
};
-int as_path_match(struct adata *path, struct f_path_mask *mask);
+int as_path_match(const struct adata *path, struct f_path_mask *mask);
+
+
+/* Counterparts to appropriate as_path_* functions */
+
+static inline int
+aggregator_16to32(byte *dst, byte *src)
+{
+ put_u32(dst, get_u16(src));
+ memcpy(dst+4, src+2, 4);
+ return 8;
+}
+
+static inline int
+aggregator_32to16(byte *dst, byte *src)
+{
+ put_u16(dst, get_u32(src));
+ memcpy(dst+2, src+4, 4);
+ return 6;
+}
+
+static inline int
+aggregator_contains_as4(struct adata *a)
+{
+ return get_u32(a->data) > 0xFFFF;
+}
+
+static inline struct adata *
+aggregator_to_old(struct linpool *pool, struct adata *a)
+{
+ struct adata *d = lp_alloc_adata(pool, 8);
+ put_u32(d->data, 0xFFFF);
+ memcpy(d->data + 4, a->data + 4, 4);
+ return d;
+}
+
/* a-set.c */
@@ -66,6 +116,7 @@ int as_path_match(struct adata *path, struct f_path_mask *mask);
/* Transitive bit (for first u32 half of EC) */
#define EC_TBIT 0x40000000
+#define ECOMM_LENGTH 8
static inline int int_set_get_size(struct adata *list)
{ return list->length / 4; }
@@ -73,6 +124,9 @@ static inline int int_set_get_size(struct adata *list)
static inline int ec_set_get_size(struct adata *list)
{ return list->length / 8; }
+static inline int lc_set_get_size(struct adata *list)
+{ return list->length / 12; }
+
static inline u32 *int_set_get_data(struct adata *list)
{ return (u32 *) list->data; }
@@ -96,17 +150,49 @@ static inline u64 ec_ip4(u64 kind, u64 key, u64 val)
static inline u64 ec_generic(u64 key, u64 val)
{ return (key << 32) | val; }
+/* Large community value */
+typedef struct lcomm {
+ u32 asn;
+ u32 ldp1;
+ u32 ldp2;
+} lcomm;
+
+#define LCOMM_LENGTH 12
+
+static inline lcomm lc_get(const u32 *l, int i)
+{ return (lcomm) { l[i], l[i+1], l[i+2] }; }
+
+static inline void lc_put(u32 *l, lcomm v)
+{ l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; }
+
+static inline int lc_match(const u32 *l, int i, lcomm v)
+{ return (l[i] == v.asn && l[i+1] == v.ldp1 && l[i+2] == v.ldp2); }
+
+static inline u32 *lc_copy(u32 *dst, const u32 *src)
+{ memcpy(dst, src, LCOMM_LENGTH); return dst + 3; }
+
+
int int_set_format(struct adata *set, int way, int from, byte *buf, uint size);
int ec_format(byte *buf, u64 ec);
int ec_set_format(struct adata *set, int from, byte *buf, uint size);
+int lc_format(byte *buf, lcomm lc);
+int lc_set_format(struct adata *set, int from, byte *buf, uint size);
int int_set_contains(struct adata *list, u32 val);
int ec_set_contains(struct adata *list, u64 val);
+int lc_set_contains(struct adata *list, lcomm val);
struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val);
+struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val);
struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val);
+struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val);
struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
+struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
+struct adata *ec_set_del_nontrans(struct linpool *pool, struct adata *set);
+struct adata *int_set_sort(struct linpool *pool, struct adata *src);
+struct adata *ec_set_sort(struct linpool *pool, struct adata *src);
+struct adata *lc_set_sort(struct linpool *pool, struct adata *src);
#endif