]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
A change in OSPF and RIP interface patterns.
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 6 May 2009 20:02:45 +0000 (22:02 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 6 May 2009 20:02:45 +0000 (22:02 +0200)
Allows to add more interface patterns to one common 'options'
section like:

interface "eth3", "eth4" { options common to eth3 and eth4 };

Also removes undocumented and unnecessary ability to specify
more interface patterns with different 'options' sections:

interface "eth3" { options ... }, "eth4" { options ... };

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

index e84377708345a3d96bbfd849737b0c0365b5b399..1d2f0150f73eac54e9524b0d8dcfa306ff3872b9 100644 (file)
@@ -18,6 +18,7 @@ CF_DEFINES
 
 static struct proto_config *this_proto;
 static struct iface_patt *this_ipatt;
+static struct iface_patt_node *this_ipn;
 static list *this_p_list;
 static struct password_item *this_p_item;
 static int password_id;
@@ -146,12 +147,36 @@ debug_default:
 
 /* Interface patterns */
 
-iface_patt:
-   TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; }
- | prefix { this_ipatt->pattern = NULL; this_ipatt->prefix = $1.addr; this_ipatt->pxlen = $1.len; }
- | TEXT prefix { this_ipatt->pattern = $1; this_ipatt->prefix = $2.addr; this_ipatt->pxlen = $2.len; }
+iface_patt_node_init:
+   /* EMPTY */ {
+     struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
+     add_tail(&this_ipatt->ipn_list, NODE ipn);
+     this_ipn = ipn;
+   }
+ ;
+
+iface_patt_node_body:
+   TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
+ | prefix { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
+ | TEXT prefix { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
+ ;
+
+iface_negate:
+       { this_ipn->positive = 1; }
+ | '-' { this_ipn->positive = 0; }
+ ;
+
+iface_patt_node:
+   iface_patt_node_init iface_negate iface_patt_node_body 
+ ;
+
+
+iface_patt_list:
+   iface_patt_node
+ | iface_patt_list ',' iface_patt_node
  ;
 
+
 /* Direct device route protocol */
 
 CF_ADDTO(proto, dev_proto '}')
@@ -167,25 +192,20 @@ dev_proto_start: proto_start DIRECT {
 dev_proto:
    dev_proto_start proto_name '{'
  | dev_proto proto_item ';'
- | dev_proto dev_iface_list ';'
+ | dev_proto dev_iface_patt ';'
  ;
 
-dev_iface_entry_init:
+dev_iface_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;
+     this_ipatt = cfg_allocz(sizeof(struct iface_patt));
+     add_tail(&p->iface_list, NODE this_ipatt);
+     init_list(&this_ipatt->ipn_list);
    }
  ;
 
-dev_iface_entry:
-   dev_iface_entry_init iface_patt
- ;
-
-dev_iface_list:
-   INTERFACE dev_iface_entry
- | dev_iface_list ',' dev_iface_entry
+dev_iface_patt:
+   INTERFACE dev_iface_init iface_patt_list
  ;
 
 /* Debug flags */
index 157a977a6b1a0602fe0317742e3f687a24cea2c2..01f258105652a3cdccb7bb0196ef062929747845 100644 (file)
@@ -543,32 +543,72 @@ if_init(void)
  *     Interface Pattern Lists
  */
 
-struct iface_patt *
-iface_patt_match(list *l, struct iface *i)
+static int
+iface_patt_match(struct iface_patt *ifp, struct iface *i)
 {
-  struct iface_patt *p;
+  struct iface_patt_node *p;
 
-  WALK_LIST(p, *l)
+  WALK_LIST(p, ifp->ipn_list)
     {
       char *t = p->pattern;
-      int ok = 1;
+      int pos = p->positive;
+
       if (t)
        {
          if (*t == '-')
            {
              t++;
-             ok = 0;
+             pos = !pos;
            }
+
          if (!patmatch(t, i->name))
            continue;
        }
-      if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen))
-       continue;
-      return ok ? p : NULL;
+
+      if (p->pxlen)
+       if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen))
+         continue;
+
+      return pos;
     }
+
+  return 0;
+}
+
+struct iface_patt *
+iface_patt_find(list *l, struct iface *i)
+{
+  struct iface_patt *p;
+
+  WALK_LIST(p, *l)
+    if (iface_patt_match(p, i))
+      return p;
+
   return NULL;
 }
 
+static int
+iface_plists_equal(struct iface_patt *pa, struct iface_patt *pb)
+{
+  struct iface_patt_node *x, *y;
+
+  x = HEAD(pa->ipn_list);
+  y = HEAD(pb->ipn_list);
+  while (x->n.next && y->n.next)
+    {
+      if ((x->positive != y->positive) ||
+         (!x->pattern && y->pattern) ||        /* This nasty lines where written by me... :-( Feela */
+         (!y->pattern && x->pattern) ||
+         ((x->pattern != y->pattern) && strcmp(x->pattern, y->pattern)) ||
+         !ipa_equal(x->prefix, y->prefix) ||
+         (x->pxlen != y->pxlen))
+       return 0;
+      x = (void *) x->n.next;
+      y = (void *) y->n.next;
+    }
+  return (!x->n.next && !y->n.next);
+}
+
 int
 iface_patts_equal(list *a, list *b, int (*comp)(struct iface_patt *, struct iface_patt *))
 {
@@ -578,13 +618,8 @@ 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 ((!x->pattern && y->pattern) ||       /* This nasty lines where written by me... :-( Feela */
-          (!y->pattern && x->pattern) ||
-          (!(x->pattern==y->pattern) &&
-          strcmp(x->pattern, y->pattern)) ||
-         !ipa_equal(x->prefix, y->prefix) ||
-         x->pxlen != y->pxlen ||
-         comp && !comp(x, y))
+      if (!iface_plists_equal(x, y) ||
+         (comp && !comp(x, y)))
        return 0;
       x = (void *) x->n.next;
       y = (void *) y->n.next;
index e37f9522d57fb37d0ec773aaf1bde549405e00e2..f884dd907ecaae8881d3b6a7e42b7166448a99ee 100644 (file)
@@ -116,16 +116,22 @@ void neigh_init(struct pool *);
  *     Interface Pattern Lists
  */
 
-struct iface_patt {
+struct iface_patt_node {
   node n;
-  byte *pattern;                       /* Interface name pattern */
-  ip_addr prefix;                      /* Interface prefix */
+  int positive;
+  byte *pattern;
+  ip_addr prefix;
   int pxlen;
+};
+
+struct iface_patt {
+  node n;
+  list ipn_list;                       /* A list of struct iface_patt_node */
 
   /* Protocol-specific data follow after this structure */
 };
 
-struct iface_patt *iface_patt_match(list *, struct iface *);
+struct iface_patt *iface_patt_find(list *, struct iface *);
 int iface_patts_equal(list *, list *, int (*)(struct iface_patt *, struct iface_patt *));
 
 #endif
index 269346decb808a7059f39a5c7420be185fa30c80..348bcc2efdc2670c33979432ee558e9935890655 100644 (file)
@@ -30,7 +30,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
   struct rt_dev_config *P = (void *) p->cf;
 
   if (!EMPTY_LIST(P->iface_list) &&
-      !iface_patt_match(&P->iface_list, ad->iface))
+      !iface_patt_find(&P->iface_list, ad->iface))
     /* Empty list is automagically treated as "*" */
     return;
   if (c & IF_CHANGE_DOWN)
index bfe2d9c834c29cb152c1dc4c89a2c33df23ea7f2..7f7d6a31559987605162f1f2561094cfb24b8646 100644 (file)
@@ -13,9 +13,9 @@ CF_HDR
 CF_DEFINES
 
 #define OSPF_CFG ((struct ospf_config *) this_proto)
-static struct ospf_area_config *this_area;
-static struct iface_patt *this_ipatt;
 #define OSPF_PATT ((struct ospf_iface_patt *) this_ipatt)
+
+static struct ospf_area_config *this_area;
 static struct nbma_node *this_nbma;
 static struct area_net_config *this_pref;
 
@@ -90,7 +90,7 @@ ospf_area_item:
    STUB COST expr { this_area->stub = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); }
  | STUB bool {if($2) { if(!this_area->stub) this_area->stub=DEFAULT_STUB_COST;}else{ this_area->stub=0;}}
  | NETWORKS '{' pref_list '}'
- | INTERFACE ospf_iface_list
+ | INTERFACE ospf_iface
  | ospf_vlink
  ;
 
@@ -122,6 +122,7 @@ ospf_vlink_start: VIRTUAL LINK idval
   if (this_area->areaid == 0) cf_error("Virtual link cannot be in backbone");
   this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
   add_tail(&this_area->vlink_list, NODE this_ipatt);
+  init_list(&this_ipatt->ipn_list);
   OSPF_PATT->vid = $3;
   OSPF_PATT->cost = COST_D;
   OSPF_PATT->helloint = HELLOINT_D;
@@ -222,6 +223,7 @@ ospf_iface_start:
  {
   this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
   add_tail(&this_area->patt_list, NODE this_ipatt);
+  init_list(&this_ipatt->ipn_list);
   OSPF_PATT->cost = COST_D;
   OSPF_PATT->helloint = HELLOINT_D;
   OSPF_PATT->pollint = POLLINT_D;
@@ -251,12 +253,7 @@ ospf_iface_opt_list:
  ;
 
 ospf_iface:
-  ospf_iface_start iface_patt ospf_iface_opt_list { finish_iface_config(OSPF_PATT); }
- ;
-
-ospf_iface_list:
-   ospf_iface
- | ospf_iface_list ',' ospf_iface
+  ospf_iface_start iface_patt_list ospf_iface_opt_list { finish_iface_config(OSPF_PATT); }
  ;
 
 opttext:
index a4c974131012c1c9a13bc3f09ac3910b6dd8b55f..5162f9f08a1689dd95b1d687508b374ce8e5d261 100644 (file)
@@ -550,7 +550,7 @@ ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
     WALK_LIST(ac, c->area_list)
     {
       if (ip = (struct ospf_iface_patt *)
-         iface_patt_match(&ac->patt_list, iface))
+         iface_patt_find(&ac->patt_list, iface))
        break;
     }
 
index 1eae376238e7d7211fbbc9ca0683540d583c4c80..0cab1d7b9c85ab4d082d1ad6f603cf32af2975e9 100644 (file)
@@ -634,11 +634,11 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
     WALK_LIST(ifa, po->iface_list)
     {
       if (oldip = (struct ospf_iface_patt *)
-         iface_patt_match(&oldac->patt_list, ifa->iface))
+         iface_patt_find(&oldac->patt_list, ifa->iface))
       {
        /* Now reconfigure interface */
        if (!(newip = (struct ospf_iface_patt *)
-             iface_patt_match(&newac->patt_list, ifa->iface)))
+             iface_patt_find(&newac->patt_list, ifa->iface)))
          return 0;
 
        /* HELLO TIMER */
index f1ae43cbd1388f4e4fb70b6173db8f1a68c0836b..9a11069e73a8aa3e98f5d6e75aa8356e01102f2e 100644 (file)
@@ -55,7 +55,7 @@ rip_cfg:
  | rip_cfg HONOR ALWAYS ';'    { RIP_CFG->honor = HO_ALWAYS; }
  | rip_cfg HONOR NEIGHBOR ';'    { RIP_CFG->honor = HO_NEIGHBOR; }
  | rip_cfg HONOR NEVER ';'    { RIP_CFG->honor = HO_NEVER; }
- | rip_cfg rip_iface_list ';'
+ | rip_cfg INTERFACE rip_iface ';'
  ;
 
 rip_auth:
@@ -64,6 +64,7 @@ rip_auth:
  | NONE { $$=AT_NONE; }
  ;
 
+
 rip_mode: 
     BROADCAST { $$=IM_BROADCAST; }
   | MULTICAST { $$=0; }
@@ -78,28 +79,26 @@ rip_iface_item:
  ;
 
 rip_iface_opts: 
-   '{'
+   /* empty */
  | rip_iface_opts rip_iface_item ';'
  ;
 
-rip_iface_opt_list: /* EMPTY */ | rip_iface_opts '}' ;
+rip_iface_opt_list:
+   /* empty */
+ | '{' rip_iface_opts '}'
+ ;
 
 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;
+     this_ipatt = cfg_allocz(sizeof(struct rip_patt));
+     add_tail(&RIP_CFG->iface_list, NODE this_ipatt);
+     init_list(&this_ipatt->ipn_list);
+     RIP_IPATT->metric = 1;
    }
  ;
 
 rip_iface:
-   rip_iface_init iface_patt rip_iface_opt_list
- ;
-
-rip_iface_list:
-   INTERFACE rip_iface
- | rip_iface_list ',' rip_iface
+   rip_iface_init iface_patt_list rip_iface_opt_list
  ;
 
 CF_ADDTO(dynamic_attr, RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_RIP_METRIC); })
index b5a4cc367244de904542ed8bfc4947e6c6f16945..12cc8783b8f21fc72a53e5135913a3840def0c33 100644 (file)
@@ -742,7 +742,7 @@ rip_real_if_add(struct object_lock *lock)
   struct iface *iface = lock->iface;
   struct proto *p = lock->data;
   struct rip_interface *rif;
-  struct iface_patt *k = iface_patt_match(&P_CF->iface_list, iface);
+  struct iface_patt *k = iface_patt_find(&P_CF->iface_list, iface);
 
   if (!k)
     bug("This can not happen! It existed few seconds ago!" );
@@ -771,7 +771,7 @@ rip_if_notify(struct proto *p, unsigned c, struct iface *iface)
     }
   }
   if (c & IF_CHANGE_UP) {
-    struct iface_patt *k = iface_patt_match(&P_CF->iface_list, iface);
+    struct iface_patt *k = iface_patt_find(&P_CF->iface_list, iface);
     struct object_lock *lock;
     struct rip_patt *PATT = (struct rip_patt *) k;