]> git.ipfire.org Git - thirdparty/bird.git/blame - nest/attrs.h
Merge branch 'master' into mq-filter-stack
[thirdparty/bird.git] / nest / attrs.h
CommitLineData
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
31struct f_tree;
32
5509e17d 33int as_path_valid(byte *data, uint len, int bs, int confed, char *err, uint elen);
4c553c5a
MM
34int as_path_16to32(byte *dst, const byte *src, uint len);
35int as_path_32to16(byte *dst, const byte *src, uint len);
d15b0b0a
OZ
36int as_path_contains_as4(const struct adata *path);
37int as_path_contains_confed(const struct adata *path);
38struct adata *as_path_strip_confed(struct linpool *pool, const struct adata *op);
5509e17d 39struct adata *as_path_prepend2(struct linpool *pool, const struct adata *op, int seq, u32 as);
d15b0b0a 40struct adata *as_path_to_old(struct linpool *pool, const struct adata *path);
4c553c5a
MM
41struct adata *as_path_cut(struct linpool *pool, const struct adata *path, uint num);
42const struct adata *as_path_merge(struct linpool *pool, const struct adata *p1, const struct adata *p2);
d15b0b0a
OZ
43void as_path_format(const struct adata *path, byte *buf, uint size);
44int as_path_getlen(const struct adata *path);
45int as_path_getlen_int(const struct adata *path, int bs);
46int as_path_get_first(const struct adata *path, u32 *orig_as);
5509e17d 47int as_path_get_first_regular(const struct adata *path, u32 *last_as);
d15b0b0a
OZ
48int as_path_get_last(const struct adata *path, u32 *last_as);
49u32 as_path_get_last_nonaggregated(const struct adata *path);
50int as_path_contains(const struct adata *path, u32 as, int min);
4c553c5a
MM
51int as_path_match_set(const struct adata *path, const struct f_tree *set);
52const struct adata *as_path_filter(struct linpool *pool, const struct adata *path, const struct f_tree *set, u32 key, int pos);
bff9ce51 53
d15b0b0a 54static 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
64struct 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
76struct f_path_mask {
77 uint len;
78 struct f_path_mask_item item[0];
79};
80
81int 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
86static inline int
4c553c5a 87aggregator_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
94static inline int
4c553c5a 95aggregator_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
102static inline int
4c553c5a 103aggregator_contains_as4(const struct adata *a)
d15b0b0a
OZ
104{
105 return get_u32(a->data) > 0xFFFF;
106}
107
108static inline struct adata *
4c553c5a 109aggregator_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
122enum ec_subtype {
123 EC_RT = 0x0002,
124 EC_RO = 0x0003,
125 EC_GENERIC = 0xFFFF,
9b46748d 126};
42a0c054 127
de12cd18
MM
128static 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 141static inline int int_set_get_size(const struct adata *list)
42a0c054
OZ
142{ return list->length / 4; }
143
4c553c5a 144static inline int ec_set_get_size(const struct adata *list)
7ccb36d3
OZ
145{ return list->length / 8; }
146
4c553c5a 147static inline int lc_set_get_size(const struct adata *list)
66dbdbd9
OZ
148{ return list->length / 12; }
149
4c553c5a 150static inline u32 *int_set_get_data(const struct adata *list)
42a0c054
OZ
151{ return (u32 *) list->data; }
152
153static inline u32 ec_hi(u64 ec) { return ec >> 32; }
154static inline u32 ec_lo(u64 ec) { return ec; }
155static 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
159static 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
163static 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
167static inline u64 ec_ip4(enum ec_subtype kind, u64 key, u64 val)
168{ return (((u64) kind | 0x0100) << 48) | (key << 16) | val; }
42a0c054
OZ
169
170static inline u64 ec_generic(u64 key, u64 val)
171{ return (key << 32) | val; }
172
66dbdbd9
OZ
173/* Large community value */
174typedef struct lcomm {
175 u32 asn;
176 u32 ldp1;
177 u32 ldp2;
178} lcomm;
179
180#define LCOMM_LENGTH 12
181
182static inline lcomm lc_get(const u32 *l, int i)
183{ return (lcomm) { l[i], l[i+1], l[i+2] }; }
184
185static inline void lc_put(u32 *l, lcomm v)
186{ l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; }
187
188static 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
191static inline u32 *lc_copy(u32 *dst, const u32 *src)
192{ memcpy(dst, src, LCOMM_LENGTH); return dst + 3; }
193
194
4c553c5a 195int int_set_format(const struct adata *set, int way, int from, byte *buf, uint size);
42a0c054 196int ec_format(byte *buf, u64 ec);
4c553c5a 197int ec_set_format(const struct adata *set, int from, byte *buf, uint size);
66dbdbd9 198int lc_format(byte *buf, lcomm lc);
4c553c5a
MM
199int lc_set_format(const struct adata *set, int from, byte *buf, uint size);
200int int_set_contains(const struct adata *list, u32 val);
201int ec_set_contains(const struct adata *list, u64 val);
202int lc_set_contains(const struct adata *list, lcomm val);
203const struct adata *int_set_prepend(struct linpool *pool, const struct adata *list, u32 val);
204const struct adata *int_set_add(struct linpool *pool, const struct adata *list, u32 val);
205const struct adata *ec_set_add(struct linpool *pool, const struct adata *list, u64 val);
206const struct adata *lc_set_add(struct linpool *pool, const struct adata *list, lcomm val);
207const struct adata *int_set_del(struct linpool *pool, const struct adata *list, u32 val);
208const struct adata *ec_set_del(struct linpool *pool, const struct adata *list, u64 val);
209const struct adata *lc_set_del(struct linpool *pool, const struct adata *list, lcomm val);
210const struct adata *int_set_union(struct linpool *pool, const struct adata *l1, const struct adata *l2);
211const struct adata *ec_set_union(struct linpool *pool, const struct adata *l1, const struct adata *l2);
212const struct adata *lc_set_union(struct linpool *pool, const struct adata *l1, const struct adata *l2);
213
214struct adata *ec_set_del_nontrans(struct linpool *pool, const struct adata *set);
215struct adata *int_set_sort(struct linpool *pool, const struct adata *src);
216struct adata *ec_set_sort(struct linpool *pool, const struct adata *src);
217struct adata *lc_set_sort(struct linpool *pool, const struct adata *src);
4847a894 218
d807ea08
OZ
219void ec_set_sort_x(struct adata *set); /* Sort in place */
220
c0668f36 221#endif