FIXME (for BGP): whole system of paths, path ~ string, path.prepend(), path.originate
FIXME: create community lists
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
static struct rte **f_rte, *f_rte_old;
static struct linpool *f_pool;
static struct ea_list **f_tmp_attrs;
+static int f_flags;
#define runtime(x) do { \
log( L_ERR x ); \
break;
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)
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) {
res.type = T_VOID;
break;
break;
}
- if (!(what->aux & EAF_TEMP)) {
+ if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_OUTGOING))) {
*f_rte = rte_do_cow(*f_rte);
l->next = (*f_rte)->attrs->eattrs;
(*f_rte)->attrs->eattrs = l;
}
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_val res;
DBG( "Running filter `%s'...", filter->name );
+ f_flags = flags;
f_tmp_attrs = tmp_attrs;
f_rte = rte;
f_rte_old = *rte;
struct ea_list;
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);
int filter_same(struct filter *new, struct filter *old);
#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
+#define FF_OUTGOING 1
+
#endif
else if (ok)
rte_trace_out(D_FILTERS, p, new, "forced accept by protocol");
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");
new = NULL;
else
{
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;
}
}
if (p->in_filter)
{
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)
{
rte_trace_in(D_FILTERS, p, new, "filtered out");
struct ea_list *tmpa = NULL;
ee = e;
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);
ia[0] = 0;