]>
git.ipfire.org Git - thirdparty/bird.git/blob - nest/attrs.h
2 * BIRD Internet Routing Daemon -- Attribute Operations
4 * (c) 2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
10 #define _BIRD_ATTRS_H_
13 #include "lib/unaligned.h"
14 #include "nest/route.h"
19 #define AS_PATH_SET 1 /* Types of path segments */
20 #define AS_PATH_SEQUENCE 2
21 #define AS_PATH_CONFED_SEQUENCE 3
22 #define AS_PATH_CONFED_SET 4
24 #define AS_PATH_MAXLEN 10000
26 #define AS_TRANS 23456
27 /* AS_TRANS is used when we need to store 32bit ASN larger than 0xFFFF
28 * to 16bit slot (like in 16bit AS_PATH). See RFC 4893 for details
33 int as_path_valid(byte
*data
, uint len
, int bs
, int confed
, char *err
, uint elen
);
34 int as_path_16to32(byte
*dst
, const byte
*src
, uint len
);
35 int as_path_32to16(byte
*dst
, const byte
*src
, uint len
);
36 int as_path_contains_as4(const struct adata
*path
);
37 int as_path_contains_confed(const struct adata
*path
);
38 struct adata
*as_path_strip_confed(struct linpool
*pool
, const struct adata
*op
);
39 struct adata
*as_path_prepend2(struct linpool
*pool
, const struct adata
*op
, int seq
, u32 as
);
40 struct adata
*as_path_to_old(struct linpool
*pool
, const struct adata
*path
);
41 struct adata
*as_path_cut(struct linpool
*pool
, const struct adata
*path
, uint num
);
42 const struct adata
*as_path_merge(struct linpool
*pool
, const struct adata
*p1
, const struct adata
*p2
);
43 void as_path_format(const struct adata
*path
, byte
*buf
, uint size
);
44 int as_path_getlen(const struct adata
*path
);
45 int as_path_getlen_int(const struct adata
*path
, int bs
);
46 int as_path_get_first(const struct adata
*path
, u32
*orig_as
);
47 int as_path_get_first_regular(const struct adata
*path
, u32
*last_as
);
48 int as_path_get_last(const struct adata
*path
, u32
*last_as
);
49 u32
as_path_get_last_nonaggregated(const struct adata
*path
);
50 int as_path_contains(const struct adata
*path
, u32 as
, int min
);
51 int as_path_match_set(const struct adata
*path
, const struct f_tree
*set
);
52 const struct adata
*as_path_filter(struct linpool
*pool
, const struct adata
*path
, const struct f_tree
*set
, u32 key
, int pos
);
54 static inline struct adata
*as_path_prepend(struct linpool
*pool
, const struct adata
*path
, u32 as
)
55 { return as_path_prepend2(pool
, path
, AS_PATH_SEQUENCE
, as
); }
62 #define PM_ASN_RANGE 4
65 struct f_path_mask_item
{
68 struct f_line
*expr
; /* PM_ASN_EXPR */
69 struct f_tree
*set
; /* PM_ASN_SET */
70 struct { /* PM_ASN_RANGE */
80 struct f_path_mask_item item
[0];
83 int as_path_match(const struct adata
*path
, const struct f_path_mask
*mask
);
86 /* Counterparts to appropriate as_path_* functions */
89 aggregator_16to32(byte
*dst
, const byte
*src
)
91 put_u32(dst
, get_u16(src
));
92 memcpy(dst
+4, src
+2, 4);
97 aggregator_32to16(byte
*dst
, const byte
*src
)
99 put_u16(dst
, get_u32(src
));
100 memcpy(dst
+2, src
+4, 4);
105 aggregator_contains_as4(const struct adata
*a
)
107 return get_u32(a
->data
) > 0xFFFF;
110 static inline struct adata
*
111 aggregator_to_old(struct linpool
*pool
, const struct adata
*a
)
113 struct adata
*d
= lp_alloc_adata(pool
, 8);
114 put_u32(d
->data
, 0xFFFF);
115 memcpy(d
->data
+ 4, a
->data
+ 4, 4);
123 /* Extended Community subtypes (kinds) */
130 static inline const char *ec_subtype_str(const enum ec_subtype ecs
) {
132 case EC_RT
: return "rt";
133 case EC_RO
: return "ro";
134 default: return NULL
;
138 /* Transitive bit (for first u32 half of EC) */
139 #define EC_TBIT 0x40000000
141 #define ECOMM_LENGTH 8
143 static inline int int_set_get_size(const struct adata
*list
)
144 { return list
->length
/ 4; }
146 static inline int ec_set_get_size(const struct adata
*list
)
147 { return list
->length
/ 8; }
149 static inline int lc_set_get_size(const struct adata
*list
)
150 { return list
->length
/ 12; }
152 static inline u32
*int_set_get_data(const struct adata
*list
)
153 { return (u32
*) list
->data
; }
155 static inline u32
ec_hi(u64 ec
) { return ec
>> 32; }
156 static inline u32
ec_lo(u64 ec
) { return ec
; }
157 static inline u64
ec_get(const u32
*l
, int i
)
158 { return (((u64
) l
[i
]) << 32) | l
[i
+1]; }
160 /* RFC 4360 3.1. Two-Octet AS Specific Extended Community */
161 static inline u64
ec_as2(enum ec_subtype kind
, u64 key
, u64 val
)
162 { return (((u64
) kind
| 0x0000) << 48) | (key
<< 32) | val
; }
164 /* RFC 5668 4-Octet AS Specific BGP Extended Community */
165 static inline u64
ec_as4(enum ec_subtype kind
, u64 key
, u64 val
)
166 { return (((u64
) kind
| 0x0200) << 48) | (key
<< 16) | val
; }
168 /* RFC 4360 3.2. IPv4 Address Specific Extended Community */
169 static inline u64
ec_ip4(enum ec_subtype kind
, u64 key
, u64 val
)
170 { return (((u64
) kind
| 0x0100) << 48) | (key
<< 16) | val
; }
172 static inline u64
ec_generic(u64 key
, u64 val
)
173 { return (key
<< 32) | val
; }
175 /* Large community value */
176 typedef struct lcomm
{
182 #define LCOMM_LENGTH 12
184 static inline lcomm
lc_get(const u32
*l
, int i
)
185 { return (lcomm
) { l
[i
], l
[i
+1], l
[i
+2] }; }
187 static inline void lc_put(u32
*l
, lcomm v
)
188 { l
[0] = v
.asn
; l
[1] = v
.ldp1
; l
[2] = v
.ldp2
; }
190 static inline int lc_match(const u32
*l
, int i
, lcomm v
)
191 { return (l
[i
] == v
.asn
&& l
[i
+1] == v
.ldp1
&& l
[i
+2] == v
.ldp2
); }
193 static inline u32
*lc_copy(u32
*dst
, const u32
*src
)
194 { memcpy(dst
, src
, LCOMM_LENGTH
); return dst
+ 3; }
197 int int_set_format(const struct adata
*set
, int way
, int from
, byte
*buf
, uint size
);
198 int ec_format(byte
*buf
, u64 ec
);
199 int ec_set_format(const struct adata
*set
, int from
, byte
*buf
, uint size
);
200 int lc_format(byte
*buf
, lcomm lc
);
201 int lc_set_format(const struct adata
*set
, int from
, byte
*buf
, uint size
);
202 int int_set_contains(const struct adata
*list
, u32 val
);
203 int ec_set_contains(const struct adata
*list
, u64 val
);
204 int lc_set_contains(const struct adata
*list
, lcomm val
);
205 const struct adata
*int_set_prepend(struct linpool
*pool
, const struct adata
*list
, u32 val
);
206 const struct adata
*int_set_add(struct linpool
*pool
, const struct adata
*list
, u32 val
);
207 const struct adata
*ec_set_add(struct linpool
*pool
, const struct adata
*list
, u64 val
);
208 const struct adata
*lc_set_add(struct linpool
*pool
, const struct adata
*list
, lcomm val
);
209 const struct adata
*int_set_del(struct linpool
*pool
, const struct adata
*list
, u32 val
);
210 const struct adata
*ec_set_del(struct linpool
*pool
, const struct adata
*list
, u64 val
);
211 const struct adata
*lc_set_del(struct linpool
*pool
, const struct adata
*list
, lcomm val
);
212 const struct adata
*int_set_union(struct linpool
*pool
, const struct adata
*l1
, const struct adata
*l2
);
213 const struct adata
*ec_set_union(struct linpool
*pool
, const struct adata
*l1
, const struct adata
*l2
);
214 const struct adata
*lc_set_union(struct linpool
*pool
, const struct adata
*l1
, const struct adata
*l2
);
216 struct adata
*ec_set_del_nontrans(struct linpool
*pool
, const struct adata
*set
);
217 struct adata
*int_set_sort(struct linpool
*pool
, const struct adata
*src
);
218 struct adata
*ec_set_sort(struct linpool
*pool
, const struct adata
*src
);
219 struct adata
*lc_set_sort(struct linpool
*pool
, const struct adata
*src
);
221 void ec_set_sort_x(struct adata
*set
); /* Sort in place */