]>
git.ipfire.org Git - thirdparty/bird.git/blob - nest/a-path.c
2 * BIRD -- Path Operations
4 * (c) 2000 Martin Mares <mj@ucw.cz>
5 * (c) 2000 Pavel Machek <pavel@ucw.cz>
7 * Can be freely distributed and used under the terms of the GNU GPL.
10 #include "nest/bird.h"
11 #include "nest/route.h"
12 #include "nest/attrs.h"
13 #include "lib/resource.h"
14 #include "lib/unaligned.h"
15 #include "lib/string.h"
18 as_path_prepend(struct linpool
*pool
, struct adata
*olda
, int as
)
22 if (olda
->length
&& olda
->data
[0] == AS_PATH_SEQUENCE
&&
23 olda
->data
[1] < 255) /* Starting with sequence => just prepend the AS number */
25 newa
= lp_alloc(pool
, sizeof(struct adata
) + olda
->length
+ 2);
26 newa
->length
= olda
->length
+ 2;
28 newa
->data
[1] = olda
->data
[1] + 1;
29 memcpy(newa
->data
+4, olda
->data
+2, olda
->length
-2);
31 else /* Create new path segment */
33 newa
= lp_alloc(pool
, sizeof(struct adata
) + olda
->length
+ 4);
34 newa
->length
= olda
->length
+ 4;
37 memcpy(newa
->data
+4, olda
->data
, olda
->length
);
39 put_u16(newa
->data
+2, as
);
44 as_path_format(struct adata
*path
, byte
*buf
, unsigned int size
)
47 byte
*e
= p
+ path
->length
- 8;
48 byte
*end
= buf
+ size
;
50 int l
, type
, isset
, as
;
59 isset
= (*p
++ == AS_PATH_SET
);
68 while (l
-- && buf
<= end
)
72 buf
+= bsprintf(buf
, "%d", get_u16(p
));
87 as_path_getlen(struct adata
*path
)
91 u8
*q
= p
+path
->length
;
98 case AS_PATH_SET
: len
= *p
++; res
++; p
+= 2*len
; break;
99 case AS_PATH_SEQUENCE
: len
= *p
++; res
+=len
; p
+= 2*len
; break;
100 default: bug("as_path_getlen: Invalid path segment");
106 #define MASK_PLUS do { mask = mask->next; if (!mask) return next == q; \
107 asterisk = (mask->val == PM_ANY); \
108 if (asterisk) { mask = mask->next; if (!mask) { return 1; } } \
112 as_path_match(struct adata
*path
, struct f_path_mask
*mask
)
117 u8
*q
= p
+path
->length
;
121 asterisk
= (mask
->val
== PM_ANY
);
123 { mask
= mask
->next
; if (!mask
) return 1; }
131 next
= p_save
+ 2*len
;
134 for (i
=0; i
<len
; i
++) {
135 if (asterisk
&& (get_u16(p
) == mask
->val
)) {
139 if (!asterisk
&& (get_u16(p
) == mask
->val
)) {
152 case AS_PATH_SEQUENCE
:
154 for (i
=0; i
<len
; i
++) {
156 if (asterisk
&& (get_u16(p
) == mask
->val
))
158 else if (!asterisk
) {
159 if (get_u16(p
) != mask
->val
)
168 bug("as_path_match: Invalid path component");