]>
Commit | Line | Data |
---|---|---|
c0668f36 MM |
1 | /* |
2 | * BIRD Internet Routing Daemon -- Attribute Operations | |
3 | * | |
4 | * (c) 2000 Martin Mares <mj@ucw.cz> | |
5 | * | |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_ATTRS_H_ | |
10 | #define _BIRD_ATTRS_H_ | |
11 | ||
46eb80d5 | 12 | #include <stdint.h> |
d15b0b0a OZ |
13 | #include "lib/unaligned.h" |
14 | #include "nest/route.h" | |
15 | ||
46eb80d5 | 16 | |
c0668f36 MM |
17 | /* a-path.c */ |
18 | ||
c6add07f MM |
19 | #define AS_PATH_SET 1 /* Types of path segments */ |
20 | #define AS_PATH_SEQUENCE 2 | |
48d79d52 OZ |
21 | #define AS_PATH_CONFED_SEQUENCE 3 |
22 | #define AS_PATH_CONFED_SET 4 | |
c6add07f | 23 | |
11cb6202 OZ |
24 | #define AS_PATH_MAXLEN 10000 |
25 | ||
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 | |
29 | */ | |
30 | ||
cc31b75a OZ |
31 | struct f_tree; |
32 | ||
5509e17d | 33 | int as_path_valid(byte *data, uint len, int bs, int confed, char *err, uint elen); |
4c553c5a MM |
34 | int as_path_16to32(byte *dst, const byte *src, uint len); |
35 | int as_path_32to16(byte *dst, const byte *src, uint len); | |
d15b0b0a OZ |
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); | |
5509e17d | 39 | struct adata *as_path_prepend2(struct linpool *pool, const struct adata *op, int seq, u32 as); |
d15b0b0a | 40 | struct adata *as_path_to_old(struct linpool *pool, const struct adata *path); |
4c553c5a MM |
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); | |
d15b0b0a OZ |
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); | |
5509e17d | 47 | int as_path_get_first_regular(const struct adata *path, u32 *last_as); |
d15b0b0a OZ |
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); | |
4c553c5a MM |
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); | |
bff9ce51 | 53 | |
d15b0b0a | 54 | static inline struct adata *as_path_prepend(struct linpool *pool, const struct adata *path, u32 as) |
5509e17d | 55 | { return as_path_prepend2(pool, path, AS_PATH_SEQUENCE, as); } |
d15b0b0a | 56 | |
11cb6202 | 57 | |
c8a6b9a3 OZ |
58 | #define PM_ASN 0 |
59 | #define PM_QUESTION 1 | |
60 | #define PM_ASTERISK 2 | |
92a72a4c | 61 | #define PM_ASN_EXPR 3 |
a0fe1944 | 62 | #define PM_ASN_RANGE 4 |
684c6f5a | 63 | |
4c553c5a MM |
64 | struct f_path_mask_item { |
65 | union { | |
66 | u32 asn; /* PM_ASN */ | |
67 | struct f_line *expr; /* PM_ASN_EXPR */ | |
68 | struct { /* PM_ASN_RANGE */ | |
69 | u32 from; | |
70 | u32 to; | |
71 | }; | |
72 | }; | |
c8a6b9a3 | 73 | int kind; |
2a40efa5 | 74 | }; |
11cb6202 | 75 | |
4c553c5a MM |
76 | struct f_path_mask { |
77 | uint len; | |
78 | struct f_path_mask_item item[0]; | |
79 | }; | |
80 | ||
81 | int as_path_match(const struct adata *path, const struct f_path_mask *mask); | |
d15b0b0a OZ |
82 | |
83 | ||
84 | /* Counterparts to appropriate as_path_* functions */ | |
85 | ||
86 | static inline int | |
4c553c5a | 87 | aggregator_16to32(byte *dst, const byte *src) |
d15b0b0a OZ |
88 | { |
89 | put_u32(dst, get_u16(src)); | |
90 | memcpy(dst+4, src+2, 4); | |
91 | return 8; | |
92 | } | |
93 | ||
94 | static inline int | |
4c553c5a | 95 | aggregator_32to16(byte *dst, const byte *src) |
d15b0b0a OZ |
96 | { |
97 | put_u16(dst, get_u32(src)); | |
98 | memcpy(dst+2, src+4, 4); | |
99 | return 6; | |
100 | } | |
101 | ||
102 | static inline int | |
4c553c5a | 103 | aggregator_contains_as4(const struct adata *a) |
d15b0b0a OZ |
104 | { |
105 | return get_u32(a->data) > 0xFFFF; | |
106 | } | |
107 | ||
108 | static inline struct adata * | |
4c553c5a | 109 | aggregator_to_old(struct linpool *pool, const struct adata *a) |
d15b0b0a OZ |
110 | { |
111 | struct adata *d = lp_alloc_adata(pool, 8); | |
112 | put_u32(d->data, 0xFFFF); | |
113 | memcpy(d->data + 4, a->data + 4, 4); | |
114 | return d; | |
115 | } | |
116 | ||
2a40efa5 | 117 | |
c6add07f MM |
118 | /* a-set.c */ |
119 | ||
42a0c054 OZ |
120 | |
121 | /* Extended Community subtypes (kinds) */ | |
4c553c5a MM |
122 | enum ec_subtype { |
123 | EC_RT = 0x0002, | |
124 | EC_RO = 0x0003, | |
125 | EC_GENERIC = 0xFFFF, | |
9b46748d | 126 | }; |
42a0c054 | 127 | |
de12cd18 MM |
128 | static inline const char *ec_subtype_str(const enum ec_subtype ecs) { |
129 | switch (ecs) { | |
130 | case EC_RT: return "rt"; | |
131 | case EC_RO: return "ro"; | |
132 | default: return NULL; | |
133 | } | |
134 | } | |
135 | ||
42a0c054 OZ |
136 | /* Transitive bit (for first u32 half of EC) */ |
137 | #define EC_TBIT 0x40000000 | |
138 | ||
66dbdbd9 | 139 | #define ECOMM_LENGTH 8 |
42a0c054 | 140 | |
4c553c5a | 141 | static inline int int_set_get_size(const struct adata *list) |
42a0c054 OZ |
142 | { return list->length / 4; } |
143 | ||
4c553c5a | 144 | static inline int ec_set_get_size(const struct adata *list) |
7ccb36d3 OZ |
145 | { return list->length / 8; } |
146 | ||
4c553c5a | 147 | static inline int lc_set_get_size(const struct adata *list) |
66dbdbd9 OZ |
148 | { return list->length / 12; } |
149 | ||
4c553c5a | 150 | static inline u32 *int_set_get_data(const struct adata *list) |
42a0c054 OZ |
151 | { return (u32 *) list->data; } |
152 | ||
153 | static inline u32 ec_hi(u64 ec) { return ec >> 32; } | |
154 | static inline u32 ec_lo(u64 ec) { return ec; } | |
155 | static inline u64 ec_get(const u32 *l, int i) | |
156 | { return (((u64) l[i]) << 32) | l[i+1]; } | |
157 | ||
158 | /* RFC 4360 3.1. Two-Octet AS Specific Extended Community */ | |
4c553c5a MM |
159 | static inline u64 ec_as2(enum ec_subtype kind, u64 key, u64 val) |
160 | { return (((u64) kind | 0x0000) << 48) | (key << 32) | val; } | |
42a0c054 OZ |
161 | |
162 | /* RFC 5668 4-Octet AS Specific BGP Extended Community */ | |
4c553c5a MM |
163 | static inline u64 ec_as4(enum ec_subtype kind, u64 key, u64 val) |
164 | { return (((u64) kind | 0x0200) << 48) | (key << 16) | val; } | |
42a0c054 OZ |
165 | |
166 | /* RFC 4360 3.2. IPv4 Address Specific Extended Community */ | |
4c553c5a MM |
167 | static inline u64 ec_ip4(enum ec_subtype kind, u64 key, u64 val) |
168 | { return (((u64) kind | 0x0100) << 48) | (key << 16) | val; } | |
42a0c054 OZ |
169 | |
170 | static inline u64 ec_generic(u64 key, u64 val) | |
171 | { return (key << 32) | val; } | |
172 | ||
66dbdbd9 OZ |
173 | /* Large community value */ |
174 | typedef struct lcomm { | |
175 | u32 asn; | |
176 | u32 ldp1; | |
177 | u32 ldp2; | |
178 | } lcomm; | |
179 | ||
180 | #define LCOMM_LENGTH 12 | |
181 | ||
182 | static inline lcomm lc_get(const u32 *l, int i) | |
183 | { return (lcomm) { l[i], l[i+1], l[i+2] }; } | |
184 | ||
185 | static inline void lc_put(u32 *l, lcomm v) | |
186 | { l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; } | |
187 | ||
188 | static inline int lc_match(const u32 *l, int i, lcomm v) | |
189 | { return (l[i] == v.asn && l[i+1] == v.ldp1 && l[i+2] == v.ldp2); } | |
190 | ||
191 | static inline u32 *lc_copy(u32 *dst, const u32 *src) | |
192 | { memcpy(dst, src, LCOMM_LENGTH); return dst + 3; } | |
193 | ||
194 | ||
4c553c5a | 195 | int int_set_format(const struct adata *set, int way, int from, byte *buf, uint size); |
42a0c054 | 196 | int ec_format(byte *buf, u64 ec); |
4c553c5a | 197 | int ec_set_format(const struct adata *set, int from, byte *buf, uint size); |
66dbdbd9 | 198 | int lc_format(byte *buf, lcomm lc); |
4c553c5a MM |
199 | int lc_set_format(const struct adata *set, int from, byte *buf, uint size); |
200 | int int_set_contains(const struct adata *list, u32 val); | |
201 | int ec_set_contains(const struct adata *list, u64 val); | |
202 | int lc_set_contains(const struct adata *list, lcomm val); | |
203 | const struct adata *int_set_prepend(struct linpool *pool, const struct adata *list, u32 val); | |
204 | const struct adata *int_set_add(struct linpool *pool, const struct adata *list, u32 val); | |
205 | const struct adata *ec_set_add(struct linpool *pool, const struct adata *list, u64 val); | |
206 | const struct adata *lc_set_add(struct linpool *pool, const struct adata *list, lcomm val); | |
207 | const struct adata *int_set_del(struct linpool *pool, const struct adata *list, u32 val); | |
208 | const struct adata *ec_set_del(struct linpool *pool, const struct adata *list, u64 val); | |
209 | const struct adata *lc_set_del(struct linpool *pool, const struct adata *list, lcomm val); | |
210 | const struct adata *int_set_union(struct linpool *pool, const struct adata *l1, const struct adata *l2); | |
211 | const struct adata *ec_set_union(struct linpool *pool, const struct adata *l1, const struct adata *l2); | |
212 | const struct adata *lc_set_union(struct linpool *pool, const struct adata *l1, const struct adata *l2); | |
213 | ||
214 | struct adata *ec_set_del_nontrans(struct linpool *pool, const struct adata *set); | |
215 | struct adata *int_set_sort(struct linpool *pool, const struct adata *src); | |
216 | struct adata *ec_set_sort(struct linpool *pool, const struct adata *src); | |
217 | struct adata *lc_set_sort(struct linpool *pool, const struct adata *src); | |
4847a894 | 218 | |
d807ea08 OZ |
219 | void ec_set_sort_x(struct adata *set); /* Sort in place */ |
220 | ||
c0668f36 | 221 | #endif |