]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Cleaned up handling of interface patterns:
authorMartin Mares <mj@ucw.cz>
Tue, 3 Aug 1999 19:30:49 +0000 (19:30 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 3 Aug 1999 19:30:49 +0000 (19:30 +0000)
   o  Parsing of interface patterns moved to generic code,
      introduced this_ipatt which works similarly to this_iface.
   o  Interface patterns now support selection by both interface
      names and primary IP addresses.
   o  Proto `direct' updated.
   o  RIP updated as well, it also seems the memory corruption
      bug there is gone.

nest/config.Y
nest/iface.c
nest/iface.h
nest/rt-dev.c
proto/rip/config.Y

index bb1328cc227dc19b5e43e73d3f5a0059da1b857f..0c6532117f024cf86270a16606a7a9af8e04aaac 100644 (file)
@@ -9,12 +9,11 @@
 CF_HDR
 
 static struct proto_config *this_proto;
+static struct iface_patt *this_ipatt;
 
 #include "nest/rt-dev.h"
 #include "nest/password.h"
 
-void rt_dev_add_iface(char *);
-
 CF_DECLS
 
 CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
@@ -102,18 +101,23 @@ rtable:
    }
  ;
 
+/* Interface patterns */
+
+iface_patt:
+   TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; }
+ | IPA pxlen { this_ipatt->pattern = NULL; this_ipatt->prefix = $1; this_ipatt->pxlen = $2; }
+ | TEXT IPA pxlen { this_ipatt->pattern = $1; this_ipatt->prefix = $2; this_ipatt->pxlen = $3; }
+ ;
+
 /* Direct device route protocol */
 
 CF_ADDTO(proto, dev_proto '}')
 
 dev_proto_start: proto_start DIRECT {
      struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config));
-     struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
      this_proto = &p->c;
      p->c.preference = DEF_PREF_DIRECT;
      init_list(&p->iface_list);
-     k->pattern = "*";
-     add_tail(&p->iface_list, &k->n);
    }
  ;
 
@@ -123,15 +127,26 @@ dev_proto:
  | dev_proto dev_iface_list ';'
  ;
 
-dev_iface_list:
-   INTERFACE TEXT {
-     /* FIXME: Beware of obscure semantics. */
-     init_list(&((struct rt_dev_config *) this_proto)->iface_list);
-     rt_dev_add_iface($2);
+dev_iface_entry_init:
+   /* EMPTY */ {
+     struct rt_dev_config *p = (void *) this_proto;
+     struct iface_patt *k = cfg_allocz(sizeof(struct iface_patt));
+     add_tail(&p->iface_list, &k->n);
+     this_ipatt = k;
    }
- | dev_iface_list ',' TEXT { rt_dev_add_iface($3); }
  ;
 
+dev_iface_entry:
+   dev_iface_entry_init iface_patt
+ ;
+
+dev_iface_list:
+   INTERFACE dev_iface_entry
+ | dev_iface_list ',' dev_iface_entry
+ ;
+
+/* Password lists */
+
 password_begin: 
    PASSWORD TEXT {
      last_password_item = cfg_alloc(sizeof (struct password_item));
@@ -162,14 +177,4 @@ password_list:
 
 CF_CODE
 
-void
-rt_dev_add_iface(char *n)
-{
-  struct rt_dev_config *p = (void *) this_proto;
-  struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
-
-  k->pattern = cfg_strdup(n);
-  add_tail(&p->iface_list, &k->n);
-}
-
 CF_END
index 19ed7fbd5dc6808cf1d648b7094df46bebbc38d7..3a5d9c6bda4ad591a8e1b58fa3c74241f3b0922e 100644 (file)
@@ -588,13 +588,19 @@ iface_patt_match(list *l, struct iface *i)
     {
       char *t = p->pattern;
       int ok = 1;
-      if (*t == '-')
+      if (t)
        {
-         t++;
-         ok = 0;
+         if (*t == '-')
+           {
+             t++;
+             ok = 0;
+           }
+         if (!patmatch(t, i->name))
+           continue;
        }
-      if (patmatch(t, i->name))
-       return ok ? p : NULL;
+      if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen))
+       continue;
+      return ok ? p : NULL;
     }
   return NULL;
 }
@@ -608,7 +614,10 @@ iface_patts_equal(list *a, list *b, int (*comp)(struct iface_patt *, struct ifac
   y = HEAD(*b);
   while (x->n.next && y->n.next)
     {
-      if (strcmp(x->pattern, y->pattern) || comp && !comp(x, y))
+      if (strcmp(x->pattern, y->pattern) ||
+         !ipa_equal(x->prefix, y->prefix) ||
+         x->pxlen != y->pxlen ||
+         comp && !comp(x, y))
        return 0;
       x = (void *) x->n.next;
       y = (void *) y->n.next;
index 1d26e7b8f16fc4cbb2f1b778be1dabbc63d75866..9f3a239556b4927e5ed3c82ad7b4276a8a8ea804 100644 (file)
@@ -122,13 +122,10 @@ void neigh_prune(void);
 struct iface_patt {
   node n;
   byte *pattern;                       /* Interface name pattern */
+  ip_addr prefix;                      /* Interface prefix */
+  int pxlen;
 
-  /* Protocol-specific data follow, but keep them like this:
-     struct rip_iface_patt {
-        struct iface_patt i;
-       whatever you (need);
-     }
-   */
+  /* Protocol-specific data follow after this structure */
 };
 
 struct iface_patt *iface_patt_match(list *, struct iface *);
index 63548fc723500f5bdbe7677c05c9ed4e3ca048cf..c07b5de616d0daf43065c4eb0dc4abac49fc4707 100644 (file)
@@ -23,7 +23,9 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
 {
   struct rt_dev_config *P = (void *) p->cf;
 
-  if (!iface_patt_match(&P->iface_list, ad->iface))
+  if (!EMPTY_LIST(P->iface_list) &&
+      !iface_patt_match(&P->iface_list, ad->iface))
+    /* Empty list is automagically treated as "*" */
     return;
   if (c & IF_CHANGE_DOWN)
     {
index 7443c44fbd9852cd5261903568bbd41779b4d54a..8590e57f9a623f4192cafd2607f41934508bc197 100644 (file)
@@ -17,10 +17,8 @@ CF_HDR
 #include "proto/rip/rip.h"
 #include "nest/iface.h"
 
-void rip_dev_add_iface(char *);
-struct rip_patt *rip_get_iface(void);
-
 #define RIP_CFG ((struct rip_proto_config *) this_proto)
+#define RIP_IPATT ((struct rip_patt *) this_ipatt)
 
 CF_DECLS
 
@@ -58,7 +56,6 @@ rip_auth:
  | NONE { $$=AT_NONE; }
  ;
 
-/* FIXME FIXME this corrupts memory */
 rip_mode: 
     BROADCAST { $$=IM_BROADCAST; }
   | QUIET     { $$=IM_QUIET; }
@@ -67,14 +64,8 @@ rip_mode:
  ;
 
 rip_iface_item:
- | METRIC expr { 
-   struct rip_patt *k = rip_get_iface();
-   k->metric = $2;
- }
- | MODE rip_mode {
-   struct rip_patt *k = rip_get_iface();
-   k->mode |= $2;
- }
+ | METRIC expr { RIP_IPATT->metric = $2; }
+ | MODE rip_mode { RIP_IPATT->mode |= $2; }
  ;
 
 rip_iface_opts: 
@@ -82,32 +73,26 @@ rip_iface_opts:
  | rip_iface_opts rip_iface_item ';'
  ;
 
-rip_iface_empty: /* EMPTY */ | rip_iface_opts '}' ;
+rip_iface_opt_list: /* EMPTY */ | rip_iface_opts '}' ;
 
-rip_iface_list:
-   INTERFACE TEXT rip_iface_empty { rip_dev_add_iface($2); }
- | dev_iface_list ',' TEXT rip_iface_empty { rip_dev_add_iface($3); }
+rip_iface_init:
+   /* EMPTY */ {
+     struct rip_patt *k = cfg_allocz(sizeof(struct rip_patt));
+     k->metric = 1;
+     add_tail(&RIP_CFG->iface_list, &k->i.n);
+     this_ipatt = &k->i;
+   }
  ;
 
-CF_CODE
+rip_iface:
+   rip_iface_init iface_patt rip_iface_opt_list
+ ;
 
-void
-rip_dev_add_iface(char *n)
-{
-  struct rip_patt *k = cfg_allocz(sizeof(struct rip_patt));
-  k->metric = 1;
-  k->i.pattern = cfg_strdup(n);
-  add_tail(&RIP_CFG->iface_list, &k->i.n);
-}
-
-struct rip_patt *
-rip_get_iface(void)
-{
-  struct rip_patt *k = TAIL(RIP_CFG->iface_list);
-  if (!k)
-    cf_error( "This cannot happen" );
-  return k;
-}
+rip_iface_list:
+   INTERFACE rip_iface
+ | rip_iface_list ',' rip_iface
+ ;
 
+CF_CODE
 
 CF_END