]> git.ipfire.org Git - thirdparty/bird.git/blob - nest/attrs.h
Filter: Allow to use sets in path masks
[thirdparty/bird.git] / nest / attrs.h
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
12 #include <stdint.h>
13 #include "lib/unaligned.h"
14 #include "nest/route.h"
15
16
17 /* a-path.c */
18
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
23
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
31 struct f_tree;
32
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);
53
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); }
56
57
58 #define PM_ASN 0
59 #define PM_QUESTION 1
60 #define PM_ASTERISK 2
61 #define PM_ASN_EXPR 3
62 #define PM_ASN_RANGE 4
63 #define PM_ASN_SET 5
64
65 struct f_path_mask_item {
66 union {
67 u32 asn; /* PM_ASN */
68 struct f_line *expr; /* PM_ASN_EXPR */
69 struct f_tree *set; /* PM_ASN_SET */
70 struct { /* PM_ASN_RANGE */
71 u32 from;
72 u32 to;
73 };
74 };
75 int kind;
76 };
77
78 struct f_path_mask {
79 uint len;
80 struct f_path_mask_item item[0];
81 };
82
83 int as_path_match(const struct adata *path, const struct f_path_mask *mask);
84
85
86 /* Counterparts to appropriate as_path_* functions */
87
88 static inline int
89 aggregator_16to32(byte *dst, const byte *src)
90 {
91 put_u32(dst, get_u16(src));
92 memcpy(dst+4, src+2, 4);
93 return 8;
94 }
95
96 static inline int
97 aggregator_32to16(byte *dst, const byte *src)
98 {
99 put_u16(dst, get_u32(src));
100 memcpy(dst+2, src+4, 4);
101 return 6;
102 }
103
104 static inline int
105 aggregator_contains_as4(const struct adata *a)
106 {
107 return get_u32(a->data) > 0xFFFF;
108 }
109
110 static inline struct adata *
111 aggregator_to_old(struct linpool *pool, const struct adata *a)
112 {
113 struct adata *d = lp_alloc_adata(pool, 8);
114 put_u32(d->data, 0xFFFF);
115 memcpy(d->data + 4, a->data + 4, 4);
116 return d;
117 }
118
119
120 /* a-set.c */
121
122
123 /* Extended Community subtypes (kinds) */
124 enum ec_subtype {
125 EC_RT = 0x0002,
126 EC_RO = 0x0003,
127 EC_GENERIC = 0xFFFF,
128 };
129
130 static inline const char *ec_subtype_str(const enum ec_subtype ecs) {
131 switch (ecs) {
132 case EC_RT: return "rt";
133 case EC_RO: return "ro";
134 default: return NULL;
135 }
136 }
137
138 /* Transitive bit (for first u32 half of EC) */
139 #define EC_TBIT 0x40000000
140
141 #define ECOMM_LENGTH 8
142
143 static inline int int_set_get_size(const struct adata *list)
144 { return list->length / 4; }
145
146 static inline int ec_set_get_size(const struct adata *list)
147 { return list->length / 8; }
148
149 static inline int lc_set_get_size(const struct adata *list)
150 { return list->length / 12; }
151
152 static inline u32 *int_set_get_data(const struct adata *list)
153 { return (u32 *) list->data; }
154
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]; }
159
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; }
163
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; }
167
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; }
171
172 static inline u64 ec_generic(u64 key, u64 val)
173 { return (key << 32) | val; }
174
175 /* Large community value */
176 typedef struct lcomm {
177 u32 asn;
178 u32 ldp1;
179 u32 ldp2;
180 } lcomm;
181
182 #define LCOMM_LENGTH 12
183
184 static inline lcomm lc_get(const u32 *l, int i)
185 { return (lcomm) { l[i], l[i+1], l[i+2] }; }
186
187 static inline void lc_put(u32 *l, lcomm v)
188 { l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; }
189
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); }
192
193 static inline u32 *lc_copy(u32 *dst, const u32 *src)
194 { memcpy(dst, src, LCOMM_LENGTH); return dst + 3; }
195
196
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);
215
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);
220
221 void ec_set_sort_x(struct adata *set); /* Sort in place */
222
223 #endif