]>
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); |
d15b0b0a OZ |
34 | int as_path_16to32(byte *dst, byte *src, uint len); |
35 | int as_path_32to16(byte *dst, 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); | |
5509e17d | 39 | struct adata *as_path_prepend2(struct linpool *pool, const struct adata *op, int seq, u32 as); |
d15b0b0a OZ |
40 | struct adata *as_path_to_old(struct linpool *pool, const struct adata *path); |
41 | void as_path_cut(struct adata *path, uint num); | |
42 | struct adata *as_path_merge(struct linpool *pool, struct adata *p1, 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); | |
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); | |
51 | int as_path_match_set(const struct adata *path, struct f_tree *set); | |
bff9ce51 OZ |
52 | struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos); |
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 | |
2a40efa5 PM |
64 | struct f_path_mask { |
65 | struct f_path_mask *next; | |
c8a6b9a3 | 66 | int kind; |
92a72a4c | 67 | uintptr_t val; |
a0fe1944 | 68 | uintptr_t val2; |
2a40efa5 | 69 | }; |
11cb6202 | 70 | |
d15b0b0a OZ |
71 | int as_path_match(const struct adata *path, struct f_path_mask *mask); |
72 | ||
73 | ||
74 | /* Counterparts to appropriate as_path_* functions */ | |
75 | ||
76 | static inline int | |
77 | aggregator_16to32(byte *dst, byte *src) | |
78 | { | |
79 | put_u32(dst, get_u16(src)); | |
80 | memcpy(dst+4, src+2, 4); | |
81 | return 8; | |
82 | } | |
83 | ||
84 | static inline int | |
85 | aggregator_32to16(byte *dst, byte *src) | |
86 | { | |
87 | put_u16(dst, get_u32(src)); | |
88 | memcpy(dst+2, src+4, 4); | |
89 | return 6; | |
90 | } | |
91 | ||
92 | static inline int | |
93 | aggregator_contains_as4(struct adata *a) | |
94 | { | |
95 | return get_u32(a->data) > 0xFFFF; | |
96 | } | |
97 | ||
98 | static inline struct adata * | |
99 | aggregator_to_old(struct linpool *pool, struct adata *a) | |
100 | { | |
101 | struct adata *d = lp_alloc_adata(pool, 8); | |
102 | put_u32(d->data, 0xFFFF); | |
103 | memcpy(d->data + 4, a->data + 4, 4); | |
104 | return d; | |
105 | } | |
106 | ||
2a40efa5 | 107 | |
c6add07f MM |
108 | /* a-set.c */ |
109 | ||
42a0c054 OZ |
110 | |
111 | /* Extended Community subtypes (kinds) */ | |
112 | #define EC_RT 0x0002 | |
113 | #define EC_RO 0x0003 | |
114 | ||
115 | #define EC_GENERIC 0xFFFF | |
116 | ||
117 | /* Transitive bit (for first u32 half of EC) */ | |
118 | #define EC_TBIT 0x40000000 | |
119 | ||
66dbdbd9 | 120 | #define ECOMM_LENGTH 8 |
42a0c054 OZ |
121 | |
122 | static inline int int_set_get_size(struct adata *list) | |
123 | { return list->length / 4; } | |
124 | ||
7ccb36d3 OZ |
125 | static inline int ec_set_get_size(struct adata *list) |
126 | { return list->length / 8; } | |
127 | ||
66dbdbd9 OZ |
128 | static inline int lc_set_get_size(struct adata *list) |
129 | { return list->length / 12; } | |
130 | ||
42a0c054 OZ |
131 | static inline u32 *int_set_get_data(struct adata *list) |
132 | { return (u32 *) list->data; } | |
133 | ||
134 | static inline u32 ec_hi(u64 ec) { return ec >> 32; } | |
135 | static inline u32 ec_lo(u64 ec) { return ec; } | |
136 | static inline u64 ec_get(const u32 *l, int i) | |
137 | { return (((u64) l[i]) << 32) | l[i+1]; } | |
138 | ||
139 | /* RFC 4360 3.1. Two-Octet AS Specific Extended Community */ | |
140 | static inline u64 ec_as2(u64 kind, u64 key, u64 val) | |
141 | { return ((kind | 0x0000) << 48) | (key << 32) | val; } | |
142 | ||
143 | /* RFC 5668 4-Octet AS Specific BGP Extended Community */ | |
144 | static inline u64 ec_as4(u64 kind, u64 key, u64 val) | |
145 | { return ((kind | 0x0200) << 48) | (key << 16) | val; } | |
146 | ||
147 | /* RFC 4360 3.2. IPv4 Address Specific Extended Community */ | |
148 | static inline u64 ec_ip4(u64 kind, u64 key, u64 val) | |
149 | { return ((kind | 0x0100) << 48) | (key << 16) | val; } | |
150 | ||
151 | static inline u64 ec_generic(u64 key, u64 val) | |
152 | { return (key << 32) | val; } | |
153 | ||
66dbdbd9 OZ |
154 | /* Large community value */ |
155 | typedef struct lcomm { | |
156 | u32 asn; | |
157 | u32 ldp1; | |
158 | u32 ldp2; | |
159 | } lcomm; | |
160 | ||
161 | #define LCOMM_LENGTH 12 | |
162 | ||
163 | static inline lcomm lc_get(const u32 *l, int i) | |
164 | { return (lcomm) { l[i], l[i+1], l[i+2] }; } | |
165 | ||
166 | static inline void lc_put(u32 *l, lcomm v) | |
167 | { l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; } | |
168 | ||
169 | static inline int lc_match(const u32 *l, int i, lcomm v) | |
170 | { return (l[i] == v.asn && l[i+1] == v.ldp1 && l[i+2] == v.ldp2); } | |
171 | ||
172 | static inline u32 *lc_copy(u32 *dst, const u32 *src) | |
173 | { memcpy(dst, src, LCOMM_LENGTH); return dst + 3; } | |
174 | ||
175 | ||
ae80a2de | 176 | int int_set_format(struct adata *set, int way, int from, byte *buf, uint size); |
42a0c054 | 177 | int ec_format(byte *buf, u64 ec); |
ae80a2de | 178 | int ec_set_format(struct adata *set, int from, byte *buf, uint size); |
66dbdbd9 OZ |
179 | int lc_format(byte *buf, lcomm lc); |
180 | int lc_set_format(struct adata *set, int from, byte *buf, uint size); | |
9c400ec9 | 181 | int int_set_contains(struct adata *list, u32 val); |
42a0c054 | 182 | int ec_set_contains(struct adata *list, u64 val); |
66dbdbd9 | 183 | int lc_set_contains(struct adata *list, lcomm val); |
261816b0 | 184 | struct adata *int_set_prepend(struct linpool *pool, struct adata *list, u32 val); |
42a0c054 OZ |
185 | struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val); |
186 | struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val); | |
66dbdbd9 | 187 | struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val); |
9c400ec9 | 188 | struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val); |
42a0c054 | 189 | struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val); |
66dbdbd9 | 190 | struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val); |
0888a737 OZ |
191 | struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2); |
192 | struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2); | |
66dbdbd9 | 193 | struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2); |
9c400ec9 | 194 | |
d15b0b0a OZ |
195 | struct adata *ec_set_del_nontrans(struct linpool *pool, struct adata *set); |
196 | struct adata *int_set_sort(struct linpool *pool, struct adata *src); | |
197 | struct adata *ec_set_sort(struct linpool *pool, struct adata *src); | |
198 | struct adata *lc_set_sort(struct linpool *pool, struct adata *src); | |
4847a894 | 199 | |
c0668f36 | 200 | #endif |