]>
git.ipfire.org Git - thirdparty/bird.git/blob - filter/f-util.c
2 * Filters: utility functions
4 * Copyright 1998 Pavel Machek <pavel@ucw.cz>
5 * 2017 Jan Maria Matejka <mq@ucw.cz>
7 * Can be freely distributed and used under the terms of the GNU GPL.
10 #include "nest/bird.h"
11 #include "conf/conf.h"
12 #include "filter/filter.h"
13 #include "filter/f-inst.h"
15 #include "nest/protocol.h"
16 #include "nest/route.h"
18 #define P(a,b) ((a<<8) | b)
21 filter_name(const struct filter
*filter
)
25 else if (filter
== FILTER_REJECT
)
27 else if (!filter
->sym
)
30 return filter
->sym
->name
;
33 void f_inst_next(struct f_inst
*first
, const struct f_inst
*append
)
38 struct filter
*f_new_where(const struct f_inst
*where
)
41 .fi_code
= FI_PRINT_AND_DIE
,
44 .i_FI_PRINT_AND_DIE
= { .fret
= F_ACCEPT
, },
48 .fi_code
= FI_PRINT_AND_DIE
,
51 .i_FI_PRINT_AND_DIE
= { .fret
= F_REJECT
, },
55 .fi_code
= FI_CONDITION
,
57 .size
= 3 + where
->size
,
65 struct filter
*f
= cfg_allocz(sizeof(struct filter
));
66 f
->root
= f_postfixify(&i
);
70 struct f_inst
*f_clear_local_vars(struct f_inst
*decls
)
72 /* Prepend instructions to clear local variables */
73 struct f_inst
*head
= NULL
;
75 for (const struct f_inst
*si
= decls
; si
; si
= si
->next
) {
76 struct f_inst
*cur
= f_new_inst(FI_CONSTANT
, (struct f_val
) { .type
= T_VOID
});
78 f_inst_next(cur
, head
);
81 head
= cur
; /* The first FI_CONSTANT put there */
87 #define CA_KEY(n) n->name, n->fda.type
88 #define CA_NEXT(n) n->next
89 #define CA_EQ(na,ta,nb,tb) (!strcmp(na,nb) && (ta == tb))
90 #define CA_FN(n,t) (mem_hash(n, strlen(n)) ^ (t*0xaae99453U))
91 #define CA_ORDER 8 /* Fixed */
94 struct ca_storage
*next
;
95 struct f_dynamic_attr fda
;
100 HASH(struct ca_storage
) ca_hash
;
102 static struct idm ca_idm
;
103 static struct ca_storage
**ca_storage
;
104 static uint ca_storage_max
;
109 struct custom_attribute
*ca
= (void *) r
;
110 struct ca_storage
*cas
= HASH_FIND(ca_hash
, CA
, ca
->name
, ca
->fda
->type
);
116 uint id
= EA_CUSTOM_ID(cas
->fda
.ea_code
);
117 idm_free(&ca_idm
, id
);
118 HASH_REMOVE(ca_hash
, CA
, cas
);
119 ca_storage
[id
] = NULL
;
127 struct custom_attribute
*ca
= (void *) r
;
128 debug("name \"%s\" id 0x%04x ea_type 0x%02x f_type 0x%02x\n",
129 ca
->name
, ca
->fda
->ea_code
, ca
->fda
->type
, ca
->fda
->f_type
);
132 static struct resclass ca_class
= {
133 .name
= "Custom attribute",
134 .size
= sizeof(struct custom_attribute
),
141 struct custom_attribute
*
142 ca_lookup(pool
*p
, const char *name
, int f_type
)
148 ea_type
= EAF_TYPE_INT
;
151 ea_type
= EAF_TYPE_IP_ADDRESS
;
154 ea_type
= EAF_TYPE_ROUTER_ID
;
157 ea_type
= EAF_TYPE_AS_PATH
;
160 ea_type
= EAF_TYPE_INT_SET
;
163 ea_type
= EAF_TYPE_EC_SET
;
166 ea_type
= EAF_TYPE_LC_SET
;
169 cf_error("Custom route attribute of unsupported type");
172 static int inited
= 0;
174 idm_init(&ca_idm
, &root_pool
, 8);
175 HASH_INIT(ca_hash
, &root_pool
, CA_ORDER
);
177 ca_storage_max
= 256;
178 ca_storage
= mb_allocz(&root_pool
, sizeof(struct ca_storage
*) * ca_storage_max
);
183 struct ca_storage
*cas
= HASH_FIND(ca_hash
, CA
, name
, ea_type
);
188 uint id
= idm_alloc(&ca_idm
);
190 if (id
>= EA_CUSTOM_BIT
)
191 cf_error("Too many custom attributes.");
193 if (id
>= ca_storage_max
) {
195 ca_storage
= mb_realloc(ca_storage
, sizeof(struct ca_storage
*) * ca_storage_max
* 2);
198 cas
= mb_allocz(&root_pool
, sizeof(struct ca_storage
) + strlen(name
) + 1);
199 cas
->fda
= f_new_dynamic_attr(ea_type
, 0, f_type
, EA_CUSTOM(id
));
202 strcpy(cas
->name
, name
);
203 ca_storage
[id
] = cas
;
205 HASH_INSERT(ca_hash
, CA
, cas
);
208 struct custom_attribute
*ca
= ralloc(p
, &ca_class
);
209 ca
->fda
= &(cas
->fda
);
210 ca
->name
= cas
->name
;
215 ea_custom_name(uint ea
)
217 uint id
= EA_CUSTOM_ID(ea
);
218 if (id
>= ca_storage_max
)
224 return ca_storage
[id
]->name
;