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"
14 #include "nest/protocol.h"
15 #include "nest/route.h"
17 #define P(a,b) ((a<<8) | b)
20 f_new_inst(enum f_instruction_code fi_code
)
23 ret
= cfg_allocz(sizeof(struct f_inst
));
24 ret
->fi_code
= fi_code
;
25 ret
->lineno
= ifs
->lino
;
30 f_new_inst_da(enum f_instruction_code fi_code
, struct f_dynamic_attr da
)
32 struct f_inst
*ret
= f_new_inst(fi_code
);
33 ret
->aux
= (da
.f_type
<< 8) | da
.type
;
34 ret
->a2
.i
= da
.ea_code
;
39 f_new_inst_sa(enum f_instruction_code fi_code
, struct f_static_attr sa
)
41 struct f_inst
*ret
= f_new_inst(fi_code
);
43 ret
->a2
.i
= sa
.sa_code
;
44 ret
->a1
.i
= sa
.readonly
;
49 * Generate set_dynamic( operation( get_dynamic(), argument ) )
52 f_generate_complex(int operation
, int operation_aux
, struct f_dynamic_attr da
, struct f_inst
*argument
)
54 struct f_inst
*set_dyn
= f_new_inst_da(FI_EA_SET
, da
),
55 *oper
= f_new_inst(operation
),
56 *get_dyn
= f_new_inst_da(FI_EA_GET
, da
);
58 oper
->aux
= operation_aux
;
60 oper
->a2
.p
= argument
;
67 f_generate_roa_check(struct rtable_config
*table
, struct f_inst
*prefix
, struct f_inst
*asn
)
69 struct f_inst_roa_check
*ret
= cfg_allocz(sizeof(struct f_inst_roa_check
));
70 ret
->i
.fi_code
= FI_ROA_CHECK
;
71 ret
->i
.lineno
= ifs
->lino
;
74 /* prefix == NULL <-> asn == NULL */
76 if (table
->addr_type
!= NET_ROA4
&& table
->addr_type
!= NET_ROA6
)
77 cf_error("%s is not a ROA table", table
->name
);
83 static const char * const f_instruction_name_str
[] = {
91 f_instruction_name(enum f_instruction_code fi
)
94 return f_instruction_name_str
[fi
];
96 bug("Got unknown instruction code: %d", fi
);
100 filter_name(struct filter
*filter
)
104 else if (filter
== FILTER_REJECT
)
106 else if (!filter
->name
)
112 #define CA_KEY(n) n->name, n->fda.type
113 #define CA_NEXT(n) n->next
114 #define CA_EQ(na,ta,nb,tb) (!strcmp(na,nb) && (ta == tb))
115 #define CA_FN(n,t) (mem_hash(n, strlen(n)) ^ (t*0xaae99453U))
116 #define CA_ORDER 8 /* Fixed */
119 struct ca_storage
*next
;
120 struct f_dynamic_attr fda
;
125 HASH(struct ca_storage
) ca_hash
;
127 static struct idm ca_idm
;
128 static struct ca_storage
**ca_storage
;
129 static uint ca_storage_max
;
134 struct custom_attribute
*ca
= (void *) r
;
135 struct ca_storage
*cas
= HASH_FIND(ca_hash
, CA
, ca
->name
, ca
->fda
->type
);
141 uint id
= EA_CUSTOM_ID(cas
->fda
.ea_code
);
142 idm_free(&ca_idm
, id
);
143 HASH_REMOVE(ca_hash
, CA
, cas
);
144 ca_storage
[id
] = NULL
;
152 struct custom_attribute
*ca
= (void *) r
;
153 debug("name \"%s\" id 0x%04x ea_type 0x%02x f_type 0x%02x\n",
154 ca
->name
, ca
->fda
->ea_code
, ca
->fda
->type
, ca
->fda
->f_type
);
157 static struct resclass ca_class
= {
158 .name
= "Custom attribute",
159 .size
= sizeof(struct custom_attribute
),
166 struct custom_attribute
*
167 ca_lookup(pool
*p
, const char *name
, int f_type
)
173 ea_type
= EAF_TYPE_INT
;
176 ea_type
= EAF_TYPE_IP_ADDRESS
;
179 ea_type
= EAF_TYPE_ROUTER_ID
;
182 ea_type
= EAF_TYPE_AS_PATH
;
185 ea_type
= EAF_TYPE_INT_SET
;
188 ea_type
= EAF_TYPE_EC_SET
;
191 ea_type
= EAF_TYPE_LC_SET
;
194 cf_error("Custom route attribute of unsupported type");
197 static int inited
= 0;
199 idm_init(&ca_idm
, &root_pool
, 8);
200 HASH_INIT(ca_hash
, &root_pool
, CA_ORDER
);
202 ca_storage_max
= 256;
203 ca_storage
= mb_allocz(&root_pool
, sizeof(struct ca_storage
*) * ca_storage_max
);
208 struct ca_storage
*cas
= HASH_FIND(ca_hash
, CA
, name
, ea_type
);
213 uint id
= idm_alloc(&ca_idm
);
215 if (id
>= EA_CUSTOM_BIT
)
216 cf_error("Too many custom attributes.");
218 if (id
>= ca_storage_max
) {
220 ca_storage
= mb_realloc(ca_storage
, sizeof(struct ca_storage
*) * ca_storage_max
* 2);
223 cas
= mb_allocz(&root_pool
, sizeof(struct ca_storage
) + strlen(name
) + 1);
224 cas
->fda
= f_new_dynamic_attr(ea_type
, f_type
, EA_CUSTOM(id
));
227 strcpy(cas
->name
, name
);
228 ca_storage
[id
] = cas
;
230 HASH_INSERT(ca_hash
, CA
, cas
);
233 struct custom_attribute
*ca
= ralloc(p
, &ca_class
);
234 ca
->fda
= &(cas
->fda
);
235 ca
->name
= cas
->name
;
240 ea_custom_name(uint ea
)
242 uint id
= EA_CUSTOM_ID(ea
);
243 if (id
>= ca_storage_max
)
249 return ca_storage
[id
]->name
;