mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 20:58:44 +00:00
f_run gets one more parameter to distinguish between in and out modes.
This commit is contained in:
parent
8d2e3eba92
commit
0a06a9b8b3
@ -9,6 +9,64 @@
|
|||||||
FIXME (for BGP): whole system of paths, path ~ string, path.prepend(), path.originate
|
FIXME (for BGP): whole system of paths, path ~ string, path.prepend(), path.originate
|
||||||
FIXME: create community lists
|
FIXME: create community lists
|
||||||
FIXME: IP addresses in ipv6
|
FIXME: IP addresses in ipv6
|
||||||
|
|
||||||
|
|
||||||
|
(1) Cesty
|
||||||
|
|
||||||
|
AS paths budtez interne reprezentovany stejne jako v BGP (viz RFC 1771),
|
||||||
|
to znamena jako posloupnost segmentu, z nichz kazdy je budto posloupnost nebo
|
||||||
|
mnozina cisel ASu. Na cestach nadefinuji nasledujici operace:
|
||||||
|
|
||||||
|
- zformatovani do stringu
|
||||||
|
- append dalsiho AS k ceste
|
||||||
|
|
||||||
|
Filtry by mely podporovat:
|
||||||
|
|
||||||
|
- operator pridani AS k ceste
|
||||||
|
- matchovani na pritomnost podposloupnosti v ceste (pricemz vyskytne-li
|
||||||
|
se tam mnozina, tak si ji lze predstavit prerovnanou v libovolnem
|
||||||
|
poradi)
|
||||||
|
- operator zjisteni delky cesty (pro vypocet metrik)
|
||||||
|
|
||||||
|
Byl bych rad, kdyby se samotne matchovaci funkce objevily v proto/bgp/attrs.c.
|
||||||
|
|
||||||
|
|
||||||
|
(2) Community-listy
|
||||||
|
|
||||||
|
Community list budiz interne reprezentovan jako posloupnost 32-bitovych cisel.
|
||||||
|
|
||||||
|
Filtry by se mely na communities divat jako na usporadane dvojice 16-bitovych
|
||||||
|
cisel (prvni je cislo AS, ktery community definoval, druhe pak community ID
|
||||||
|
v ramci AS) a melo by byt mozne definovat si konstanty typu community.
|
||||||
|
K dispozici by mely byt nasledujici operace:
|
||||||
|
|
||||||
|
- zjisteni pritomnosti community v listu
|
||||||
|
- pridani community do listu
|
||||||
|
- odebrani community z listu
|
||||||
|
- zresetovani listu
|
||||||
|
|
||||||
|
Pro operace na cestach i na community listech by se mela pouzivat `teckova'
|
||||||
|
notace pouzita v mem puvodnim navrhu syntaxe.
|
||||||
|
|
||||||
|
|
||||||
|
(3) Zmeny v semantice dynamickych atributu
|
||||||
|
|
||||||
|
Aby se nemusely neustale kopirovat seznamy atributu, rad bych provedl jeste
|
||||||
|
jednu zmenu v tom, jak filtry nakladaji s atributy (pevne doufam, ze posledni,
|
||||||
|
ale uznavam, ze u te predchozi jsem to take tvrdil): Funkci f_run budiz
|
||||||
|
pridan jeste jeden parametr, ktery prepina mezi dvema mody:
|
||||||
|
|
||||||
|
(a) [incoming filter mode] Jako nyni.
|
||||||
|
|
||||||
|
(b) [outgoing filter mode] Pokud se hleda atribut, hleda se nejdrive
|
||||||
|
v tmp_attrs a pokud to selze, tak v rta->attrs. Pokud se nastavuje,
|
||||||
|
dava se _vzdy_ do tmp_attrs.
|
||||||
|
|
||||||
|
Diky tomu filtry pri exportu routes nebudou vubec muset modifikovat rta a
|
||||||
|
protokoly, ktere v import_control potrebuji nastavovat i non-temporary
|
||||||
|
atributy, je budou moci pridat do tmp_attrs, aniz by sahly na rta.
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CF_HDR
|
CF_HDR
|
||||||
|
@ -145,6 +145,7 @@ val_print(struct f_val v)
|
|||||||
static struct rte **f_rte, *f_rte_old;
|
static struct rte **f_rte, *f_rte_old;
|
||||||
static struct linpool *f_pool;
|
static struct linpool *f_pool;
|
||||||
static struct ea_list **f_tmp_attrs;
|
static struct ea_list **f_tmp_attrs;
|
||||||
|
static int f_flags;
|
||||||
|
|
||||||
#define runtime(x) do { \
|
#define runtime(x) do { \
|
||||||
log( L_ERR x ); \
|
log( L_ERR x ); \
|
||||||
@ -329,9 +330,14 @@ interpret(struct f_inst *what)
|
|||||||
break;
|
break;
|
||||||
case P('e','a'): /* Access to extended attributes */
|
case P('e','a'): /* Access to extended attributes */
|
||||||
{
|
{
|
||||||
eattr *e = ea_find( (*f_rte)->attrs->eattrs, what->a2.i );
|
eattr *e = NULL;
|
||||||
|
if (!(f_flags & FF_OUTGOING))
|
||||||
|
e = ea_find( (*f_rte)->attrs->eattrs, what->a2.i );
|
||||||
if (!e)
|
if (!e)
|
||||||
e = ea_find( (*f_tmp_attrs), what->a2.i );
|
e = ea_find( (*f_tmp_attrs), what->a2.i );
|
||||||
|
if ((!e) && (f_flags & FF_OUTGOING))
|
||||||
|
e = ea_find( (*f_rte)->attrs->eattrs, what->a2.i );
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
res.type = T_VOID;
|
res.type = T_VOID;
|
||||||
break;
|
break;
|
||||||
@ -371,7 +377,7 @@ interpret(struct f_inst *what)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(what->aux & EAF_TEMP)) {
|
if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_OUTGOING))) {
|
||||||
*f_rte = rte_do_cow(*f_rte);
|
*f_rte = rte_do_cow(*f_rte);
|
||||||
l->next = (*f_rte)->attrs->eattrs;
|
l->next = (*f_rte)->attrs->eattrs;
|
||||||
(*f_rte)->attrs->eattrs = l;
|
(*f_rte)->attrs->eattrs = l;
|
||||||
@ -523,12 +529,13 @@ i_same(struct f_inst *f1, struct f_inst *f2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool)
|
f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags)
|
||||||
{
|
{
|
||||||
struct f_inst *inst;
|
struct f_inst *inst;
|
||||||
struct f_val res;
|
struct f_val res;
|
||||||
DBG( "Running filter `%s'...", filter->name );
|
DBG( "Running filter `%s'...", filter->name );
|
||||||
|
|
||||||
|
f_flags = flags;
|
||||||
f_tmp_attrs = tmp_attrs;
|
f_tmp_attrs = tmp_attrs;
|
||||||
f_rte = rte;
|
f_rte = rte;
|
||||||
f_rte_old = *rte;
|
f_rte_old = *rte;
|
||||||
|
@ -67,7 +67,7 @@ int same_tree(struct f_tree *t1, struct f_tree *t2);
|
|||||||
struct ea_list;
|
struct ea_list;
|
||||||
struct rte;
|
struct rte;
|
||||||
|
|
||||||
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool);
|
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
|
||||||
char *filter_name(struct filter *filter);
|
char *filter_name(struct filter *filter);
|
||||||
int filter_same(struct filter *new, struct filter *old);
|
int filter_same(struct filter *new, struct filter *old);
|
||||||
|
|
||||||
@ -122,4 +122,6 @@ struct f_tree {
|
|||||||
|
|
||||||
#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
|
#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
|
||||||
|
|
||||||
|
#define FF_OUTGOING 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -141,7 +141,7 @@ do_rte_announce(struct announce_hook *a, net *net, rte *new, rte *old, ea_list *
|
|||||||
else if (ok)
|
else if (ok)
|
||||||
rte_trace_out(D_FILTERS, p, new, "forced accept by protocol");
|
rte_trace_out(D_FILTERS, p, new, "forced accept by protocol");
|
||||||
else if (p->out_filter == FILTER_REJECT ||
|
else if (p->out_filter == FILTER_REJECT ||
|
||||||
p->out_filter && f_run(p->out_filter, &new, &tmpa, rte_update_pool) > F_ACCEPT)
|
p->out_filter && f_run(p->out_filter, &new, &tmpa, rte_update_pool, 0) > F_ACCEPT)
|
||||||
{
|
{
|
||||||
rte_trace_out(D_FILTERS, p, new, "filtered out");
|
rte_trace_out(D_FILTERS, p, new, "filtered out");
|
||||||
new = NULL;
|
new = NULL;
|
||||||
@ -155,7 +155,7 @@ do_rte_announce(struct announce_hook *a, net *net, rte *new, rte *old, ea_list *
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ea_list *tmpb = p->make_tmp_attrs ? p->make_tmp_attrs(old, rte_update_pool) : NULL;
|
ea_list *tmpb = p->make_tmp_attrs ? p->make_tmp_attrs(old, rte_update_pool) : NULL;
|
||||||
if (f_run(p->out_filter, &old, &tmpb, rte_update_pool) > F_ACCEPT)
|
if (f_run(p->out_filter, &old, &tmpb, rte_update_pool, 0) > F_ACCEPT)
|
||||||
old = NULL;
|
old = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,7 +387,7 @@ rte_update(rtable *table, net *net, struct proto *p, rte *new)
|
|||||||
if (p->in_filter)
|
if (p->in_filter)
|
||||||
{
|
{
|
||||||
ea_list *old_tmpa = tmpa;
|
ea_list *old_tmpa = tmpa;
|
||||||
int fr = f_run(p->in_filter, &new, &tmpa, rte_update_pool);
|
int fr = f_run(p->in_filter, &new, &tmpa, rte_update_pool, 0);
|
||||||
if (fr > F_ACCEPT)
|
if (fr > F_ACCEPT)
|
||||||
{
|
{
|
||||||
rte_trace_in(D_FILTERS, p, new, "filtered out");
|
rte_trace_in(D_FILTERS, p, new, "filtered out");
|
||||||
@ -695,7 +695,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
|||||||
struct ea_list *tmpa = NULL;
|
struct ea_list *tmpa = NULL;
|
||||||
ee = e;
|
ee = e;
|
||||||
rte_update_lock(); /* We use the update buffer for filtering */
|
rte_update_lock(); /* We use the update buffer for filtering */
|
||||||
if (d->filter == FILTER_ACCEPT || f_run(d->filter, &ee, &tmpa, rte_update_pool) <= F_ACCEPT)
|
if (d->filter == FILTER_ACCEPT || f_run(d->filter, &ee, &tmpa, rte_update_pool, 0) <= F_ACCEPT)
|
||||||
{
|
{
|
||||||
rt_show_rte(c, ia, e, d);
|
rt_show_rte(c, ia, e, d);
|
||||||
ia[0] = 0;
|
ia[0] = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user