]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
f_run gets one more parameter to distinguish between in and out modes.
authorPavel Machek <pavel@ucw.cz>
Wed, 29 Mar 2000 09:02:00 +0000 (09:02 +0000)
committerPavel Machek <pavel@ucw.cz>
Wed, 29 Mar 2000 09:02:00 +0000 (09:02 +0000)
filter/config.Y
filter/filter.c
filter/filter.h
nest/rt-table.c

index 00aeefc185ca521a9b3064764628f248a4a8a5d4..413e88cb55a9fc51806087f0b46618536bd460ac 100644 (file)
@@ -9,6 +9,64 @@
        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
index 5faabfefa4c2b77615d4035680e032f83f3dec47..6a590725862ccc9e6ec3614152ec97ca4227a545 100644 (file)
@@ -145,6 +145,7 @@ val_print(struct f_val v)
 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 ); \
@@ -329,9 +330,14 @@ interpret(struct f_inst *what)
     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;
@@ -371,7 +377,7 @@ interpret(struct f_inst *what)
        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;
@@ -523,12 +529,13 @@ i_same(struct f_inst *f1, struct f_inst *f2)
 }
 
 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;
index 3f05f6a32cb91120486ba80bb622f3dda6f028a1..b05e6a7a70f318d00e0a702b60f9512770a72d8e 100644 (file)
@@ -67,7 +67,7 @@ int same_tree(struct f_tree *t1, struct f_tree *t2);
 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);
 
@@ -122,4 +122,6 @@ struct f_tree {
 
 #define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
 
+#define FF_OUTGOING 1
+
 #endif
index d3fcf64af12ebf855afa69e57b1f318306299e6b..687e9402a6f204a90714eaff17f35379df044766 100644 (file)
@@ -141,7 +141,7 @@ do_rte_announce(struct announce_hook *a, net *net, rte *new, rte *old, ea_list *
       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;
@@ -155,7 +155,7 @@ do_rte_announce(struct announce_hook *a, net *net, rte *new, rte *old, ea_list *
       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;
        }
     }
@@ -387,7 +387,7 @@ rte_update(rtable *table, net *net, struct proto *p, rte *new)
       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");
@@ -695,7 +695,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
       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;